[pypy-svn] r68249 - pypy/branch/gc-compress/pypy/rpython/memory
arigo at codespeak.net
arigo at codespeak.net
Thu Oct 8 16:59:57 CEST 2009
Author: arigo
Date: Thu Oct 8 16:59:54 2009
New Revision: 68249
Modified:
pypy/branch/gc-compress/pypy/rpython/memory/gctypelayout.py
Log:
Stop trying to be clever about the 3 lower bits of the typeid.
Instead just use a bit field in the type table.
Modified: pypy/branch/gc-compress/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/memory/gctypelayout.py (original)
+++ pypy/branch/gc-compress/pypy/rpython/memory/gctypelayout.py Thu Oct 8 16:59:54 2009
@@ -17,6 +17,7 @@
# structure describing the layout of a typeid
TYPE_INFO = lltype.Struct("type_info",
+ ("infobits", lltype.Signed), # combination of the T_xxx consts
("finalizer", FINALIZERTYPE),
("fixedsize", lltype.Signed),
("ofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)),
@@ -24,7 +25,6 @@
("ofstovar", lltype.Signed),
("ofstolength", lltype.Signed),
("varofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)),
- ("weakptrofs", lltype.Signed),
)
TYPE_INFO_TABLE = lltype.Array(TYPE_INFO)
@@ -36,16 +36,18 @@
def q_is_varsize(self, typeid):
ll_assert(typeid > 0, "invalid type_id")
- return (typeid & T_IS_FIXSIZE) == 0
+ infobits = self.type_info_table[typeid].infobits
+ return (infobits & T_IS_VARSIZE) != 0
def q_has_gcptr_in_varsize(self, typeid):
ll_assert(typeid > 0, "invalid type_id")
- return (typeid & (T_IS_FIXSIZE|T_NO_GCPTR_IN_VARSIZE)) == 0
+ infobits = self.type_info_table[typeid].infobits
+ return (infobits & T_HAS_GCPTR_IN_VARSIZE) != 0
def q_is_gcarrayofgcptr(self, typeid):
ll_assert(typeid > 0, "invalid type_id")
- return (typeid &
- (T_IS_FIXSIZE|T_NO_GCPTR_IN_VARSIZE|T_NOT_SIMPLE_GCARRAY)) == 0
+ infobits = self.type_info_table[typeid].infobits
+ return (infobits & T_IS_GCARRAY_OF_GCPTR) != 0
def q_finalizer(self, typeid):
ll_assert(typeid > 0, "invalid type_id")
@@ -77,7 +79,10 @@
def q_weakpointer_offset(self, typeid):
ll_assert(typeid > 0, "invalid type_id")
- return self.type_info_table[typeid].weakptrofs
+ infobits = self.type_info_table[typeid].infobits
+ if infobits & T_IS_WEAKREF:
+ return weakptr_offset
+ return -1
def set_query_functions(self, gc):
gc.set_query_functions(
@@ -93,58 +98,20 @@
self.q_varsize_offsets_to_gcpointers_in_var_part,
self.q_weakpointer_offset)
-# For the q_xxx functions that return flags, we use bit patterns
-# in the typeid instead of entries in the type_info_table. The
-# following flag combinations are used (the idea being that it's
-# very fast on CPUs to check if all flags in a set are all zero):
-
-# * if T_IS_FIXSIZE is set, the gc object is not var-sized
-# * if T_IS_FIXSIZE and T_NO_GCPTR_IN_VARSIZE are both cleared,
-# there are gc ptrs in the var-sized part
-# * if T_IS_FIXSIZE, T_NO_GCPTR_IN_VARSIZE and T_NOT_SIMPLE_GCARRAY
-# are all cleared, the shape is just like GcArray(gcptr)
-
-T_IS_FIXSIZE = 0x4
-T_NO_GCPTR_IN_VARSIZE = 0x2
-T_NOT_SIMPLE_GCARRAY = 0x1
-
-def get_typeid_bitmask(TYPE):
- """Return the bits that we would like to be set or cleared in the type_id
- corresponding to TYPE. This returns (mask, expected_value), where
- the condition is that 'type_id & mask == expected_value'.
- """
- if not TYPE._is_varsize():
- return (T_IS_FIXSIZE, T_IS_FIXSIZE) # not var-sized
-
- if (isinstance(TYPE, lltype.GcArray)
- and isinstance(TYPE.OF, lltype.Ptr)
- and TYPE.OF.TO._gckind == 'gc'):
- # a simple GcArray(gcptr)
- return (T_IS_FIXSIZE|T_NO_GCPTR_IN_VARSIZE|T_NOT_SIMPLE_GCARRAY, 0)
- if isinstance(TYPE, lltype.Struct):
- ARRAY = TYPE._flds[TYPE._arrayfld]
- else:
- ARRAY = TYPE
- assert isinstance(ARRAY, lltype.Array)
- if ARRAY.OF != lltype.Void and len(offsets_to_gc_pointers(ARRAY.OF)) > 0:
- # var-sized, with gc pointers in the variable part
- return (T_IS_FIXSIZE|T_NO_GCPTR_IN_VARSIZE|T_NOT_SIMPLE_GCARRAY,
- T_NOT_SIMPLE_GCARRAY)
- else:
- # var-sized, but no gc pointer in the variable part
- return (T_IS_FIXSIZE|T_NO_GCPTR_IN_VARSIZE, T_NO_GCPTR_IN_VARSIZE)
+T_IS_VARSIZE = 0x01
+T_HAS_GCPTR_IN_VARSIZE = 0x02
+T_IS_GCARRAY_OF_GCPTR = 0x04
+T_IS_WEAKREF = 0x08
def encode_type_shape(builder, info, TYPE):
"""Encode the shape of the TYPE into the TYPE_INFO structure 'info'."""
offsets = offsets_to_gc_pointers(TYPE)
+ infobits = 0
info.ofstoptrs = builder.offsets2table(offsets, TYPE)
info.finalizer = builder.make_finalizer_funcptr_for_type(TYPE)
- info.weakptrofs = weakpointer_offset(TYPE)
if not TYPE._is_varsize():
- #info.isvarsize = False
- #info.gcptrinvarsize = False
info.fixedsize = llarena.round_up_for_allocation(
llmemory.sizeof(TYPE))
info.ofstolength = -1
@@ -153,7 +120,7 @@
# varsize ones, the GC must anyway compute the size at run-time
# and round up that result.
else:
- #info.isvarsize = True
+ infobits |= T_IS_VARSIZE
info.fixedsize = llmemory.sizeof(TYPE, 0)
if isinstance(TYPE, lltype.Struct):
ARRAY = TYPE._flds[TYPE._arrayfld]
@@ -161,7 +128,11 @@
info.ofstolength = ofs1 + llmemory.ArrayLengthOffset(ARRAY)
info.ofstovar = ofs1 + llmemory.itemoffsetof(ARRAY, 0)
else:
+ assert isinstance(TYPE, lltype.GcArray)
ARRAY = TYPE
+ if (isinstance(ARRAY.OF, lltype.Ptr)
+ and ARRAY.OF.TO._gckind == 'gc'):
+ infobits |= T_IS_GCARRAY_OF_GCPTR
info.ofstolength = llmemory.ArrayLengthOffset(ARRAY)
info.ofstovar = llmemory.itemoffsetof(TYPE, 0)
assert isinstance(ARRAY, lltype.Array)
@@ -169,12 +140,13 @@
offsets = offsets_to_gc_pointers(ARRAY.OF)
else:
offsets = ()
+ if len(offsets) > 0:
+ infobits |= T_HAS_GCPTR_IN_VARSIZE
info.varofstoptrs = builder.offsets2table(offsets, ARRAY.OF)
info.varitemsize = llmemory.sizeof(ARRAY.OF)
- #info.gcptrinvarsize = len(offsets) > 0
- #info.gcarrayofgcptr = (isinstance(TYPE, lltype.GcArray)
- # and isinstance(TYPE.OF, lltype.Ptr)
- # and TYPE.OF.TO._gckind == 'gc')
+ if TYPE == WEAKREF:
+ infobits |= T_IS_WEAKREF
+ info.infobits = infobits
# ____________________________________________________________
@@ -199,7 +171,6 @@
self.all_prebuilt_gc = []
self.finalizer_funcptrs = {}
self.offsettable_cache = {}
- self.next_typeid_cache = {}
def get_type_id(self, TYPE):
try:
@@ -211,27 +182,16 @@
# It goes into a list for now, which will be turned into a
# TYPE_INFO_TABLE in flatten_table() by the gc transformer.
- # pick the next type_id with the correct bits set or cleared
- mask, expected = get_typeid_bitmask(TYPE)
- type_id = self.next_typeid_cache.get((mask, expected), 1)
- while True:
- if type_id == len(self.type_info_list):
- self.type_info_list.append(None)
- if (self.type_info_list[type_id] is None and
- (type_id & mask) == expected):
- break # can use this type_id
- else:
- type_id += 1 # continue searching
- self.next_typeid_cache[mask, expected] = type_id + 1
- assert type_id & 0xffff == type_id # make sure it fits into 2 bytes
-
# build the TYPE_INFO structure
info = lltype.malloc(GCData.TYPE_INFO, immortal=True, zero=True)
if self.can_encode_type_shape:
encode_type_shape(self, info, TYPE)
else:
self._pending_type_shapes.append((info, TYPE))
- self.type_info_list[type_id] = info
+ # store it
+ type_id = len(self.type_info_list)
+ assert type_id & 0xffff == type_id # make sure it fits into 2 bytes
+ self.type_info_list.append(info)
self.id_of_type[TYPE] = type_id
return type_id
@@ -268,7 +228,7 @@
fieldnames = GCData.TYPE_INFO._names
for tableentry, newcontent in zip(table, self.type_info_list):
if newcontent is None: # empty entry
- tableentry.weakptrofs = -1
+ tableentry.infobits = 0
tableentry.ofstolength = -1
else:
for name in fieldnames:
@@ -349,11 +309,6 @@
offsets.append(0)
return offsets
-def weakpointer_offset(TYPE):
- if TYPE == WEAKREF:
- return llmemory.offsetof(WEAKREF, "weakptr")
- return -1
-
def gc_pointers_inside(v, adr, mutable_only=False):
t = lltype.typeOf(v)
if isinstance(t, lltype.Struct):
@@ -409,6 +364,7 @@
sizeof_weakref= llmemory.sizeof(WEAKREF)
empty_weakref = lltype.malloc(WEAKREF, immortal=True)
empty_weakref.weakptr = llmemory.NULL
+weakptr_offset = llmemory.offsetof(WEAKREF, "weakptr")
def ll_weakref_deref(wref):
wref = llmemory.cast_weakrefptr_to_ptr(WEAKREFPTR, wref)
More information about the Pypy-commit
mailing list