Author: Armin Rigo <[email protected]>
Branch:
Changeset: r58778:358b96dcce46
Date: 2012-11-07 11:37 +0100
http://bitbucket.org/pypy/pypy/changeset/358b96dcce46/
Log: C implementation.
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -91,6 +91,11 @@
def OP_GC_STACK_BOTTOM(self, funcgen, op):
return ''
+ def OP_GC_GCFLAG_EXTRA(self, funcgen, op):
+ return '%s = 0; /* gc_gcflag_extra%r */' % (
+ funcgen.expr(op.result),
+ op.args[0])
+
class RefcountingInfo:
static_deallocator = None
@@ -370,16 +375,23 @@
config = self.db.translator.config
return config.translation.gcremovetypeptr
+ def header_type(self, extra='*'):
+ # Fish out the C name of the 'struct pypy_header0'
+ HDR = self.db.gctransformer.HDR
+ return self.db.gettype(HDR).replace('@', extra)
+
+ def tid_fieldname(self, tid_field='tid'):
+ # Fish out the C name of the tid field.
+ HDR = self.db.gctransformer.HDR
+ hdr_node = self.db.gettypedefnode(HDR)
+ return hdr_node.c_struct_field_name(tid_field)
+
def OP_GC_GETTYPEPTR_GROUP(self, funcgen, op):
# expands to a number of steps, as per rpython/lltypesystem/opimpl.py,
# all implemented by a single call to a C macro.
[v_obj, c_grpptr, c_skipoffset, c_vtableinfo] = op.args
+ tid_field = c_vtableinfo.value[2]
typename = funcgen.db.gettype(op.result.concretetype)
- 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->'
'_gcheader.%s, %s);'
@@ -387,12 +399,36 @@
cdecl(typename, ''),
funcgen.expr(c_grpptr),
funcgen.expr(v_obj),
- fieldname,
+ self.tid_fieldname(tid_field),
funcgen.expr(c_skipoffset)))
def OP_GC_ASSUME_YOUNG_POINTERS(self, funcgen, op):
raise Exception("the FramewokGCTransformer should handle this")
+ def OP_GC_GCFLAG_EXTRA(self, funcgen, op):
+ gcflag_extra = self.db.gctransformer.gcdata.gc.gcflag_extra
+ if gcflag_extra == 0:
+ return BasicGcPolicy.OP_GC_GCFLAG_EXTRA(self, funcgen, op)
+ subopnum = op.args[0].value
+ if subopnum == 1:
+ return '%s = 1; /* has_gcflag_extra */' % (
+ funcgen.expr(op.result),)
+ hdrfield = '((%s)%s)->%s' % (self.header_type(),
+ funcgen.expr(op.args[1]),
+ self.tid_fieldname())
+ parts = ['%s = (%s & %dL) != 0;' % (funcgen.expr(op.result),
+ hdrfield,
+ gcflag_extra)]
+ if subopnum == 2: # get_gcflag_extra
+ parts.append('/* get_gcflag_extra */')
+ elif subopnum == 3: # toggle_gcflag_extra
+ parts.insert(0, '%s ^= %dL;' % (hdrfield,
+ gcflag_extra))
+ parts.append('/* toggle_gcflag_extra */')
+ else:
+ raise AssertionError(subopnum)
+ return ' '.join(parts)
+
class ShadowStackFrameworkGcPolicy(BasicFrameworkGcPolicy):
def gettransformer(self):
diff --git a/pypy/translator/c/test/test_newgc.py
b/pypy/translator/c/test/test_newgc.py
--- a/pypy/translator/c/test/test_newgc.py
+++ b/pypy/translator/c/test/test_newgc.py
@@ -1183,6 +1183,35 @@
assert data.startswith('member0')
assert 'GcArray of * GcStruct S {' in data
+ def define_gcflag_extra(self):
+ class A:
+ pass
+ a1 = A()
+ def fn():
+ a2 = A()
+ if not rgc.has_gcflag_extra():
+ return 0 # cannot test it then
+ assert rgc.get_gcflag_extra(a1) == False
+ assert rgc.get_gcflag_extra(a2) == False
+ rgc.toggle_gcflag_extra(a1)
+ assert rgc.get_gcflag_extra(a1) == True
+ assert rgc.get_gcflag_extra(a2) == False
+ rgc.toggle_gcflag_extra(a2)
+ assert rgc.get_gcflag_extra(a1) == True
+ assert rgc.get_gcflag_extra(a2) == True
+ rgc.toggle_gcflag_extra(a1)
+ assert rgc.get_gcflag_extra(a1) == False
+ assert rgc.get_gcflag_extra(a2) == True
+ rgc.toggle_gcflag_extra(a2)
+ assert rgc.get_gcflag_extra(a1) == False
+ assert rgc.get_gcflag_extra(a2) == False
+ return 0
+ return fn
+
+ def test_gcflag_extra(self):
+ self.run("gcflag_extra")
+
+
class TestSemiSpaceGC(TestUsingFramework, snippet.SemiSpaceGCTestDefines):
gcpolicy = "semispace"
should_be_moving = True
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit