Author: Alex Gaynor <[email protected]>
Branch: erase-raw-mem
Changeset: r53409:216539421090
Date: 2012-03-12 21:51 -0700
http://bitbucket.org/pypy/pypy/changeset/216539421090/
Log: added gc support for untyped stuff via new gc_writebarrier llop
diff --git a/pypy/rpython/memory/gctransform/framework.py
b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -233,7 +233,7 @@
# for tests
self.frameworkgc__teardown_ptr = getfn(frameworkgc__teardown, [],
annmodel.s_None)
-
+
if root_walker.need_root_stack:
self.incr_stack_ptr = getfn(root_walker.incr_stack,
[annmodel.SomeInteger()],
@@ -248,7 +248,7 @@
self.decr_stack_ptr = None
self.weakref_deref_ptr = self.inittime_helper(
ll_weakref_deref, [llmemory.WeakRefPtr], llmemory.Address)
-
+
classdef = bk.getuniqueclassdef(GCClass)
s_gc = annmodel.SomeInstance(classdef)
s_gcref = annmodel.SomePtr(llmemory.GCREF)
@@ -313,6 +313,13 @@
[s_gc, annmodel.SomeInteger(knowntype=llgroup.r_halfword)],
annmodel.SomeInteger())
+ if hasattr(GCClass, 'write_barrier'):
+ self.wb_ptr = getfn(GCClass.write_barrier.im_func,
+ [s_gc] + [annmodel.SomeAddress()] * 2,
+ annmodel.s_None)
+ elif GCClass.needs_write_barrier:
+ raise NotImplementedError("Add a write_barrier")
+
if hasattr(GCClass, 'writebarrier_before_copy'):
self.wb_before_copy_ptr = \
getfn(GCClass.writebarrier_before_copy.im_func,
@@ -638,7 +645,7 @@
if self.collect_analyzer.analyze_direct_call(graph):
raise Exception("'no_collect' function can trigger collection:"
" %s" % func)
-
+
if self.write_barrier_ptr:
self.clean_sets = (
find_initializing_stores(self.collect_analyzer, graph))
@@ -905,6 +912,19 @@
TYPE = v_ob.concretetype.TO
gen_zero_gc_pointers(TYPE, v_ob, hop.llops)
+ def gct_gc_writebarrier(self, hop):
+ op = hop.spaceop
+ if not hasattr(self, "wb_ptr"):
+ return
+
+ newvalue_addr = hop.genop('cast_ptr_to_adr', [op.args[0]],
+ resulttype=llmemory.Address)
+ struct_addr = hop.genop('cast_ptr_to_adr', [op.args[1]],
+ resulttype=llmemory.Address)
+ hop.genop('direct_call',
+ [self.wb_ptr, self.c_const_gc, newvalue_addr, struct_addr])
+
+
def gct_gc_writebarrier_before_copy(self, hop):
op = hop.spaceop
if not hasattr(self, 'wb_before_copy_ptr'):
diff --git a/pypy/rpython/memory/gctransform/transform.py
b/pypy/rpython/memory/gctransform/transform.py
--- a/pypy/rpython/memory/gctransform/transform.py
+++ b/pypy/rpython/memory/gctransform/transform.py
@@ -377,6 +377,9 @@
def gct_zero_gc_pointers_inside(self, hop):
pass
+ def gct_gc_writebarrier(self, hop):
+ pass
+
def gct_gc_writebarrier_before_copy(self, hop):
# We take the conservative default and return False here, meaning
# that rgc.ll_arraycopy() will do the copy by hand (i.e. with a
@@ -520,11 +523,11 @@
flags = hop.spaceop.args[1].value
flavor = flags['flavor']
meth = getattr(self, 'gct_fv_%s_malloc' % flavor, None)
- assert meth, "%s has no support for malloc with flavor %r" % (self,
flavor)
+ assert meth, "%s has no support for malloc with flavor %r" % (self,
flavor)
c_size = rmodel.inputconst(lltype.Signed, llmemory.sizeof(TYPE))
v_raw = meth(hop, flags, TYPE, c_size)
hop.cast_result(v_raw)
-
+
def gct_fv_raw_malloc(self, hop, flags, TYPE, c_size):
v_raw = hop.genop("direct_call", [self.raw_malloc_fixedsize_ptr,
c_size],
resulttype=llmemory.Address)
@@ -548,7 +551,7 @@
flavor = flags['flavor']
assert flavor != 'cpy', "cannot malloc CPython objects directly"
meth = getattr(self, 'gct_fv_%s_malloc_varsize' % flavor, None)
- assert meth, "%s has no support for malloc_varsize with flavor %r" %
(self, flavor)
+ assert meth, "%s has no support for malloc_varsize with flavor %r" %
(self, flavor)
return self.varsize_malloc_helper(hop, flags, meth, [])
def gct_malloc_nonmovable(self, *args, **kwds):
diff --git a/pypy/rpython/memory/test/test_transformed_gc.py
b/pypy/rpython/memory/test/test_transformed_gc.py
--- a/pypy/rpython/memory/test/test_transformed_gc.py
+++ b/pypy/rpython/memory/test/test_transformed_gc.py
@@ -13,6 +13,7 @@
from pypy import conftest
from pypy.rlib.rstring import StringBuilder
from pypy.rlib.rarithmetic import LONG_BIT
+from pypy.rlib.rerased_raw import UntypedStorage
WORD = LONG_BIT // 8
@@ -834,7 +835,7 @@
from pypy.translator.translator import graphof
from pypy.objspace.flow.model import Constant
from pypy.rpython.lltypesystem import rffi
- layoutbuilder = cls.ensure_layoutbuilder(translator)
+ layoutbuilder = cls.ensure_layoutbuilder(translator)
type_id = layoutbuilder.get_type_id(P)
#
# now fix the do_malloc_fixedsize_clear in the graph of g
@@ -928,6 +929,25 @@
run = self.runner("writebarrier_before_copy")
run([])
+ def define_untyped_storage(cls):
+ class A(object):
+ def __init__(self, v):
+ self.v = v
+
+ def fn():
+ s = UntypedStorage("io")
+ s.setint(0, 10)
+ s.setinstance(1, A(10))
+ rgc.collect()
+ return s.getint(0) + s.getinstance(1, A).v
+ return fn
+
+ def test_untyped_storage(self):
+ run = self.runner("untyped_storage")
+ res = run([])
+ assert res == 20
+
+
# ________________________________________________________________
class TestMarkSweepGC(GenericGCTests):
@@ -1152,7 +1172,7 @@
def test_adr_of_nursery(self):
run = self.runner("adr_of_nursery")
- res = run([])
+ res = run([])
class TestGenerationalNoFullCollectGC(GCTest):
# test that nursery is doing its job and that no full collection
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
@@ -12,6 +12,7 @@
from pypy.translator.interactive import Translation
from pypy.annotation import policy as annpolicy
from pypy import conftest
+from pypy.rlib.rerased_raw import UntypedStorage
class TestUsingFramework(object):
gcpolicy = "marksweep"
@@ -80,7 +81,7 @@
funcsstr.append(func)
funcs0.append(None)
funcs1.append(None)
- else:
+ else:
numargs = len(inspect.getargspec(func)[0])
funcsstr.append(None)
if numargs == 0:
@@ -1185,6 +1186,24 @@
assert data.startswith('member0')
assert 'GcArray of * GcStruct S {' in data
+ def define_untyped_storage(cls):
+ class A(object):
+ def __init__(self, v):
+ self.v = v
+
+ def fn():
+ s = UntypedStorage("io")
+ s.setint(0, 10)
+ s.setinstance(1, A(10))
+ rgc.collect()
+ return s.getint(0) + s.getinstance(1, A).v
+ return fn
+
+ def test_untyped_storage(self):
+ res = self.run("untyped_storage")
+ assert res == 20
+
+
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