[pypy-svn] r51755 - in pypy/branch/unified-rtti/pypy: rpython/memory rpython/memory/gctransform translator/c
arigo at codespeak.net
arigo at codespeak.net
Thu Feb 21 18:19:35 CET 2008
Author: arigo
Date: Thu Feb 21 18:19:33 2008
New Revision: 51755
Modified:
pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/framework.py
pypy/branch/unified-rtti/pypy/rpython/memory/gctypelayout.py
pypy/branch/unified-rtti/pypy/translator/c/gc.py
Log:
In-progress.
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/framework.py Thu Feb 21 18:19:33 2008
@@ -5,7 +5,6 @@
from pypy.rpython import rmodel
from pypy.rpython.memory import gctypelayout
from pypy.rpython.memory.gc import marksweep
-from pypy.rpython.memory.gcheader import GCHeaderBuilder
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rlib.debug import ll_assert
from pypy.translator.backendopt import graphanalyze
@@ -332,12 +331,6 @@
self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc)
self.needs_zero_gc_pointers = GCClass.needs_zero_gc_pointers
- HDR = self._gc_HDR = self.gcdata.gc.gcheaderbuilder.HDR
- self._gc_fields = fields = []
- for fldname in HDR._names:
- FLDTYPE = getattr(HDR, fldname)
- fields.append(('_' + fldname, FLDTYPE))
-
def build_root_walker(self):
return ShadowStackRootWalker(self)
@@ -351,14 +344,6 @@
def finalizer_funcptr_for_type(self, TYPE):
return self.layoutbuilder.finalizer_funcptr_for_type(TYPE)
- def gc_fields(self):
- return self._gc_fields
-
- def gc_field_values_for(self, obj):
- hdr = self.gcdata.gc.gcheaderbuilder.header_of_object(obj)
- HDR = self._gc_HDR
- return [getattr(hdr, fldname) for fldname in HDR._names]
-
def finish_tables(self):
table = self.layoutbuilder.flatten_table()
log.info("assigned %s typeids" % (len(table), ))
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctypelayout.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctypelayout.py Thu Feb 21 18:19:33 2008
@@ -15,8 +15,9 @@
ADDRESS_VOID_FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
FINALIZERTYPE = lltype.Ptr(ADDRESS_VOID_FUNC)
- # structure describing the layout of a typeid
+ # structure describing the layout of a type
TYPE_INFO = lltype.Struct("type_info",
+ ("flags", lltype.Signed), # T_... flags, see below
("finalizer", FINALIZERTYPE),
("fixedsize", lltype.Signed),
("ofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)),
@@ -26,58 +27,39 @@
("varofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)),
("weakptrofs", lltype.Signed),
)
- TYPE_INFO_TABLE = lltype.Array(TYPE_INFO)
- def __init__(self, type_info_table):
- self.type_info_table = type_info_table
- # 'type_info_table' is a list of TYPE_INFO structures when
- # running with gcwrapper, or a real TYPE_INFO_TABLE after
- # the gctransformer.
-
- def q_is_varsize(self, typeid):
- ll_assert(typeid > 0, "invalid type_id")
- return (typeid & T_IS_FIXSIZE) == 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
-
- 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
-
- def q_finalizer(self, typeid):
- ll_assert(typeid > 0, "invalid type_id")
- return self.type_info_table[typeid].finalizer
-
- def q_offsets_to_gc_pointers(self, typeid):
- ll_assert(typeid > 0, "invalid type_id")
- return self.type_info_table[typeid].ofstoptrs
-
- def q_fixed_size(self, typeid):
- ll_assert(typeid > 0, "invalid type_id")
- return self.type_info_table[typeid].fixedsize
-
- def q_varsize_item_sizes(self, typeid):
- ll_assert(typeid > 0, "invalid type_id")
- return self.type_info_table[typeid].varitemsize
-
- def q_varsize_offset_to_variable_part(self, typeid):
- ll_assert(typeid > 0, "invalid type_id")
- return self.type_info_table[typeid].ofstovar
-
- def q_varsize_offset_to_length(self, typeid):
- ll_assert(typeid > 0, "invalid type_id")
- return self.type_info_table[typeid].ofstolength
-
- def q_varsize_offsets_to_gcpointers_in_var_part(self, typeid):
- ll_assert(typeid > 0, "invalid type_id")
- return self.type_info_table[typeid].varofstoptrs
-
- def q_weakpointer_offset(self, typeid):
- ll_assert(typeid > 0, "invalid type_id")
- return self.type_info_table[typeid].weakptrofs
+ def q_is_varsize(self, typeinfo):
+ return (typeinfo.flags & T_IS_VARSIZE) != 0
+
+ def q_has_gcptr_in_varsize(self, typeinfo):
+ return (typeinfo.flags & T_HAS_GCPTR_IN_VARSIZE) != 0
+
+ def q_is_gcarrayofgcptr(self, typeinfo):
+ return (typeinfo.flags & T_IS_GCARRAYOFGCPTR) != 0
+
+ def q_finalizer(self, typeinfo):
+ return typeinfo.finalizer
+
+ def q_offsets_to_gc_pointers(self, typeinfo):
+ return typeinfo.ofstoptrs
+
+ def q_fixed_size(self, typeinfo):
+ return typeinfo.fixedsize
+
+ def q_varsize_item_sizes(self, typeinfo):
+ return typeinfo.varitemsize
+
+ def q_varsize_offset_to_variable_part(self, typeinfo):
+ return typeinfo.ofstovar
+
+ def q_varsize_offset_to_length(self, typeinfo):
+ return typeinfo.ofstolength
+
+ def q_varsize_offsets_to_gcpointers_in_var_part(self, typeinfo):
+ return typeinfo.varofstoptrs
+
+ def q_weakpointer_offset(self, typeinfo):
+ return typeinfo.weakptrofs
def set_query_functions(self, gc):
gc.set_query_functions(
@@ -93,34 +75,27 @@
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'.
+# For the q_xxx functions that return flags, we use bits in the 'flags'
+# field. The idea is that at some point, some GCs could copy these bits
+# into the header of each object to allow for an indirection-free decoding.
+# (Not all combinations of the 3 flags are meaningful; in fact, only 4 are)
+
+T_IS_VARSIZE = 0x1
+T_HAS_GCPTR_IN_VARSIZE = 0x2
+T_IS_GCARRAYOFGCPTR = 0x4
+T_first_unused_bit = 0x8
+
+def get_type_flags(TYPE):
+ """Compute the 'flags' for the type.
"""
if not TYPE._is_varsize():
- return (T_IS_FIXSIZE, T_IS_FIXSIZE) # not var-sized
+ return 0 # 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)
+ return T_IS_VARSIZE | T_HAS_GCPTR_IN_VARSIZE | T_IS_GCARRAYOFGCPTR
if isinstance(TYPE, lltype.Struct):
ARRAY = TYPE._flds[TYPE._arrayfld]
@@ -129,22 +104,20 @@
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)
+ return T_IS_VARSIZE | T_HAS_GCPTR_IN_VARSIZE
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)
+ return T_IS_VARSIZE
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)
+ info.flags = get_type_flags(TYPE)
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 +126,6 @@
# varsize ones, the GC must anyway compute the size at run-time
# and round up that result.
else:
- #info.isvarsize = True
info.fixedsize = llmemory.sizeof(TYPE, 0)
if isinstance(TYPE, lltype.Struct):
ARRAY = TYPE._flds[TYPE._arrayfld]
@@ -174,20 +146,14 @@
offsets = ()
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')
# ____________________________________________________________
class TypeLayoutBuilder(object):
- can_add_new_types = True
def __init__(self):
- self.type_info_list = [None] # don't use typeid 0, helps debugging
- self.id_of_type = {} # {LLTYPE: type_id}
+ self.typeinfos = {} # {LLTYPE: TYPE_INFO}
self.seen_roots = {}
# the following are lists of addresses of gc pointers living inside the
# prebuilt structures. It should list all the locations that could
@@ -202,38 +168,17 @@
self.additional_roots_sources = 0
self.finalizer_funcptrs = {}
self.offsettable_cache = {}
- self.next_typeid_cache = {}
- def get_type_id(self, TYPE):
+ def get_type_info(self, TYPE):
try:
- return self.id_of_type[TYPE]
+ return self.typeinfos[TYPE]
except KeyError:
- assert self.can_add_new_types
assert isinstance(TYPE, (lltype.GcStruct, lltype.GcArray))
- # Record the new type_id description as a TYPE_INFO structure.
- # 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
+ # Record the new type description as a TYPE_INFO structure.
info = lltype.malloc(GCData.TYPE_INFO, immortal=True, zero=True)
encode_type_shape(self, info, TYPE)
- self.type_info_list[type_id] = info
- self.id_of_type[TYPE] = type_id
- return type_id
+ self.typeinfos[TYPE] = info
+ return info
def offsets2table(self, offsets, TYPE):
try:
@@ -246,21 +191,6 @@
self.offsettable_cache[TYPE] = cachedarray
return cachedarray
- def flatten_table(self):
- self.can_add_new_types = False
- self.offsettable_cache = None
- table = lltype.malloc(GCData.TYPE_INFO_TABLE, len(self.type_info_list),
- immortal=True)
- 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.ofstolength = -1
- else:
- for name in fieldnames:
- setattr(tableentry, name, getattr(newcontent, name))
- return table
-
def finalizer_funcptr_for_type(self, TYPE):
if TYPE in self.finalizer_funcptrs:
return self.finalizer_funcptrs[TYPE]
@@ -283,10 +213,10 @@
self.seen_roots[id(value)] = True
if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)):
- typeid = self.get_type_id(TYPE)
+ typeinfo = self.get_type_info(TYPE)
hdr = gc.gcheaderbuilder.new_header(value)
adr = llmemory.cast_ptr_to_adr(hdr)
- gc.init_gc_object_immortal(adr, typeid)
+ gc.init_gc_object_immortal(adr, typeinfo)
# The following collects the addresses of all the fields that have
# a GC Pointer type, inside the current prebuilt object. All such
Modified: pypy/branch/unified-rtti/pypy/translator/c/gc.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/gc.py (original)
+++ pypy/branch/unified-rtti/pypy/translator/c/gc.py Thu Feb 21 18:19:33 2008
@@ -158,12 +158,6 @@
args = [funcgen.expr(v) for v in op.args]
return '%s = %s; /* for moving GCs */' % (args[1], args[0])
- def common_gcheader_definition(self, defnode):
- return defnode.db.gctransformer.gc_fields()
-
- def common_gcheader_initdata(self, defnode):
- o = top_container(defnode.obj)
- return defnode.db.gctransformer.gc_field_values_for(o)
class StacklessFrameworkGcPolicy(FrameworkGcPolicy):
transformerclass = stacklessframework.StacklessFrameworkGCTransformer
More information about the Pypy-commit
mailing list