PageRenderTime 39ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/rpython/memory/gcheader.py

https://github.com/thepian/pypy
Python | 47 lines | 32 code | 11 blank | 4 comment | 1 complexity | 75ea6073d63a8a131ca68d1238ec8ec0 MD5 | raw file
  1. import weakref
  2. from pypy.rpython.lltypesystem import lltype, llmemory
  3. # this is global because a header cannot be a header of more than one GcObj
  4. header2obj = weakref.WeakKeyDictionary()
  5. class GCHeaderBuilder(object):
  6. def __init__(self, HDR):
  7. """NOT_RPYTHON"""
  8. self.HDR = HDR
  9. self.obj2header = weakref.WeakKeyDictionary()
  10. self.size_gc_header = llmemory.GCHeaderOffset(self)
  11. def header_of_object(self, gcptr):
  12. # XXX hackhackhack
  13. gcptr = gcptr._as_obj(check=False)
  14. if isinstance(gcptr, llmemory._gctransformed_wref):
  15. return self.obj2header[gcptr._ptr._as_obj(check=False)]
  16. return self.obj2header[gcptr]
  17. def object_from_header(headerptr):
  18. return header2obj[headerptr._as_obj(check=False)]
  19. object_from_header = staticmethod(object_from_header)
  20. def get_header(self, gcptr):
  21. return self.obj2header.get(gcptr._as_obj(check=False), None)
  22. def attach_header(self, gcptr, headerptr):
  23. gcobj = gcptr._as_obj()
  24. assert gcobj not in self.obj2header
  25. # sanity checks
  26. assert gcobj._TYPE._gckind == 'gc'
  27. assert not isinstance(gcobj._TYPE, lltype.GcOpaqueType)
  28. assert not gcobj._parentstructure()
  29. self.obj2header[gcobj] = headerptr
  30. header2obj[headerptr._obj] = gcptr._as_ptr()
  31. def new_header(self, gcptr):
  32. headerptr = lltype.malloc(self.HDR, immortal=True)
  33. self.attach_header(gcptr, headerptr)
  34. return headerptr
  35. def _freeze_(self):
  36. return True # for reads of size_gc_header