[pypy-svn] r73634 - in pypy/trunk/pypy: rpython/memory/gctransform translator/c
benjamin at codespeak.net
benjamin at codespeak.net
Sun Apr 11 01:57:57 CEST 2010
Author: benjamin
Date: Sun Apr 11 01:57:55 2010
New Revision: 73634
Modified:
pypy/trunk/pypy/rpython/memory/gctransform/framework.py
pypy/trunk/pypy/translator/c/gc.py
pypy/trunk/pypy/translator/c/node.py
Log:
make the gc header inlined by the C compiler
This makes us follow strict aliasing correctly as well as simplifying genc a
bit.
Modified: pypy/trunk/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/trunk/pypy/rpython/memory/gctransform/framework.py Sun Apr 11 01:57:55 2010
@@ -445,11 +445,7 @@
self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc)
self.malloc_zero_filled = GCClass.malloc_zero_filled
- 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))
+ HDR = self.HDR = self.gcdata.gc.gcheaderbuilder.HDR
size_gc_header = self.gcdata.gc.gcheaderbuilder.size_gc_header
vtableinfo = (HDR, size_gc_header, self.gcdata.gc.typeid_is_in_field)
@@ -472,17 +468,13 @@
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, needs_hash=False):
+ def gc_header_for(self, obj, needs_hash=False):
hdr = self.gcdata.gc.gcheaderbuilder.header_of_object(obj)
- HDR = self._gc_HDR
+ HDR = self.HDR
withhash, flag = self.gcdata.gc.withhash_flag_is_in_field
- result = []
for fldname in HDR._names:
- x = getattr(hdr, fldname)
if fldname == withhash:
+ x = getattr(hdr, fldname)
TYPE = lltype.typeOf(x)
x = lltype.cast_primitive(lltype.Signed, x)
if needs_hash:
@@ -490,8 +482,8 @@
else:
x &= ~flag # clear the flag in the header
x = lltype.cast_primitive(TYPE, x)
- result.append(x)
- return result
+ setattr(hdr, fldname, x)
+ return hdr
def get_hash_offset(self, T):
type_id = self.get_type_id(T)
Modified: pypy/trunk/pypy/translator/c/gc.py
==============================================================================
--- pypy/trunk/pypy/translator/c/gc.py (original)
+++ pypy/trunk/pypy/translator/c/gc.py Sun Apr 11 01:57:55 2010
@@ -20,16 +20,13 @@
def common_gcheader_definition(self, defnode):
if defnode.db.gctransformer is not None:
- HDR = defnode.db.gctransformer.HDR
- return [(name, HDR._flds[name]) for name in HDR._names]
- else:
- return []
+ return defnode.db.gctransformer.HDR
+ return None
def common_gcheader_initdata(self, defnode):
if defnode.db.gctransformer is not None:
raise NotImplementedError
- else:
- return []
+ return None
def struct_gcheader_definition(self, defnode):
return self.common_gcheader_definition(defnode)
@@ -113,11 +110,9 @@
def common_gcheader_initdata(self, defnode):
if defnode.db.gctransformer is not None:
gct = defnode.db.gctransformer
- hdr = gct.gcheaderbuilder.header_of_object(top_container(defnode.obj))
- HDR = gct.HDR
- return [getattr(hdr, fldname) for fldname in HDR._names]
- else:
- return []
+ top = top_container(defnode.obj)
+ return gct.gcheaderbuilder.header_of_object(top)._obj
+ return None
# for structs
@@ -196,9 +191,10 @@
def common_gcheader_initdata(self, defnode):
if defnode.db.gctransformer is not None:
- return [lltype.identityhash_nocache(defnode.obj._as_ptr())]
- else:
- return []
+ hdr = lltype.malloc(defnode.db.gctransformer.HDR, immortal=True)
+ hdr.hash = lltype.identityhash_nocache(defnode.obj._as_ptr())
+ return hdr._obj
+ return None
def array_setup(self, arraydefnode):
pass
@@ -333,13 +329,11 @@
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)
needs_hash = self.get_prebuilt_hash(o) is not None
- return defnode.db.gctransformer.gc_field_values_for(o, needs_hash)
+ hdr = defnode.db.gctransformer.gc_header_for(o, needs_hash)
+ return hdr._obj
def get_prebuilt_hash(self, obj):
# for prebuilt objects that need to have their hash stored and
@@ -362,9 +356,14 @@
# all implemented by a single call to a C macro.
[v_obj, c_grpptr, c_skipoffset, c_vtableinfo] = op.args
typename = funcgen.db.gettype(op.result.concretetype)
- fieldname = c_vtableinfo.value[2]
+ tid_field = c_vtableinfo.value[2]
+ # Fish out the C name of the tid field.
+ HDR = self.db.gctransformer.HDR
+ hdr_node = self.db.gettypedefnode(HDR)
+ fieldname = hdr_node.c_struct_field_name(tid_field)
return (
- '%s = (%s)_OP_GET_NEXT_GROUP_MEMBER(%s, (pypy_halfword_t)%s->_%s, %s);'
+ '%s = (%s)_OP_GET_NEXT_GROUP_MEMBER(%s, (pypy_halfword_t)%s->'
+ '_gcheader.%s, %s);'
% (funcgen.expr(op.result),
cdecl(typename, ''),
funcgen.expr(c_grpptr),
Modified: pypy/trunk/pypy/translator/c/node.py
==============================================================================
--- pypy/trunk/pypy/translator/c/node.py (original)
+++ pypy/trunk/pypy/translator/c/node.py Sun Apr 11 01:57:55 2010
@@ -88,8 +88,10 @@
if self.varlength != 1:
self.normalizedtypename = db.gettype(STRUCT, who_asks=self)
if needs_gcheader(self.STRUCT):
- for fname, T in db.gcpolicy.struct_gcheader_definition(self):
- self.fields.append((fname, db.gettype(T, who_asks=self)))
+ HDR = db.gcpolicy.struct_gcheader_definition(self)
+ if HDR is not None:
+ gc_field = ("_gcheader", db.gettype(HDR, who_asks=self))
+ self.fields.append(gc_field)
for name in self.fieldnames:
T = self.c_struct_field_type(name)
if name == STRUCT._arrayfld:
@@ -218,8 +220,10 @@
if self.varlength != 1:
self.normalizedtypename = db.gettype(ARRAY, who_asks=self)
if needs_gcheader(ARRAY):
- for fname, T in db.gcpolicy.array_gcheader_definition(self):
- self.gcfields.append((fname, db.gettype(T, who_asks=self)))
+ HDR = db.gcpolicy.array_gcheader_definition(self)
+ if HDR is not None:
+ gc_field = ("_gcheader", db.gettype(HDR, who_asks=self))
+ self.gcfields.append(gc_field)
self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
def computegcinfo(self):
@@ -558,12 +562,12 @@
data = []
if needs_gcheader(self.T):
- for i, thing in enumerate(self.db.gcpolicy.struct_gcheader_initdata(self)):
- data.append(('gcheader%d'%i, thing))
-
+ gc_init = self.db.gcpolicy.struct_gcheader_initdata(self)
+ data.append(('gcheader', gc_init))
+
for name in defnode.fieldnames:
data.append((name, getattr(self.obj, name)))
-
+
# Reasonably, you should only initialise one of the fields of a union
# in C. This is possible with the syntax '.fieldname value' or
# '.fieldname = value'. But here we don't know which of the
@@ -665,12 +669,11 @@
defnode = self.db.gettypedefnode(self.T)
yield '{'
if needs_gcheader(self.T):
- for i, thing in enumerate(self.db.gcpolicy.array_gcheader_initdata(self)):
- lines = generic_initializationexpr(self.db, thing,
- 'gcheader%d'%i,
- '%sgcheader%d' % (decoration, i))
- for line in lines:
- yield line
+ gc_init = self.db.gcpolicy.array_gcheader_initdata(self)
+ lines = generic_initializationexpr(self.db, gc_init, 'gcheader',
+ '%sgcheader' % (decoration,))
+ for line in lines:
+ yield line
if self.T._hints.get('nolength', False):
length = ''
else:
More information about the Pypy-commit
mailing list