[pypy-commit] pypy gc-del: Minimal support for register_finalizer() in the JIT
arigo
noreply at buildbot.pypy.org
Sat Apr 27 10:03:00 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: gc-del
Changeset: r63675:bc7623f7e088
Date: 2013-04-27 10:05 +0200
http://bitbucket.org/pypy/pypy/changeset/bc7623f7e088/
Log: Minimal support for register_finalizer() in the JIT
diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -534,7 +534,7 @@
if self.layoutbuilder is not None:
type_id = self.layoutbuilder.get_type_id(S)
assert not self.layoutbuilder.is_weakref_type(S)
- assert not self.layoutbuilder.has_finalizer(S)
+ assert not self.layoutbuilder.has_destructor(S)
descr.tid = llop.combine_ushort(lltype.Signed, type_id, 0)
def init_array_descr(self, A, descr):
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -482,6 +482,7 @@
rewrite_op_ullong_mod_zer = _do_builtin_call
rewrite_op_gc_identityhash = _do_builtin_call
rewrite_op_gc_id = _do_builtin_call
+ rewrite_op_gc_register_finalizer = _do_builtin_call
rewrite_op_uint_mod = _do_builtin_call
rewrite_op_cast_float_to_uint = _do_builtin_call
rewrite_op_cast_uint_to_float = _do_builtin_call
diff --git a/rpython/jit/codewriter/support.py b/rpython/jit/codewriter/support.py
--- a/rpython/jit/codewriter/support.py
+++ b/rpython/jit/codewriter/support.py
@@ -217,7 +217,6 @@
def _ll_1_gc_identityhash(x):
return lltype.identityhash(x)
-
# the following function should not be "@elidable": I can think of
# a corner case in which id(const) is constant-folded, and then 'const'
# disappears and is collected too early (possibly causing another object
@@ -225,6 +224,9 @@
def _ll_1_gc_id(ptr):
return llop.gc_id(lltype.Signed, ptr)
+def _ll_2_gc_register_finalizer(obj, func):
+ return llop.gc_register_finalizer(lltype.Void, obj, func)
+
@oopspec("jit.force_virtual(inst)")
def _ll_1_jit_force_virtual(inst):
@@ -839,6 +841,9 @@
def get_gcid_oopspec(op):
return 'gc_id', op.args
+def get_gcregisterfinalizer_oopspec(op):
+ return 'gc_register_finalizer', op.args
+
RENAMED_ADT_NAME = {
'list': {
@@ -871,6 +876,8 @@
return get_identityhash_oopspec(op)
elif op.opname == 'gc_id':
return get_gcid_oopspec(op)
+ elif op.opname == 'gc_register_finalizer':
+ return get_gcregisterfinalizer_oopspec(op)
else:
raise ValueError(op.opname)
diff --git a/rpython/jit/codewriter/test/test_flatten.py b/rpython/jit/codewriter/test/test_flatten.py
--- a/rpython/jit/codewriter/test/test_flatten.py
+++ b/rpython/jit/codewriter/test/test_flatten.py
@@ -11,7 +11,7 @@
from rpython.rlib.rarithmetic import ovfcheck, r_uint, r_longlong, r_ulonglong
from rpython.rlib.jit import dont_look_inside, _we_are_jitted, JitDriver
from rpython.rlib.objectmodel import keepalive_until_here
-from rpython.rlib import jit
+from rpython.rlib import jit, rgc
class FakeRegAlloc:
@@ -999,6 +999,19 @@
float_return %(result_var)s
""" % {"result_var": result_var, "tmp_var": tmp_var}, transform=True)
+ def test_register_finalizer(self):
+ class A(object):
+ def finalizer(self):
+ pass
+ glob_a = A()
+ def f():
+ rgc.register_finalizer(glob_a.finalizer)
+ self.encoding_test(f, [], """
+ residual_call_ir_v $<* fn gc_register_finalizer>, I[$<* fn A.finalizer>], R[$<* struct object>], <Descr>
+ -live-
+ void_return
+ """, transform=True)
+
def check_force_cast(FROM, TO, operations, value):
"""Check that the test is correctly written..."""
diff --git a/rpython/jit/metainterp/test/test_del.py b/rpython/jit/metainterp/test/test_del.py
--- a/rpython/jit/metainterp/test/test_del.py
+++ b/rpython/jit/metainterp/test/test_del.py
@@ -123,8 +123,34 @@
res = self.meta_interp(main, [20])
assert res == 1001
+
class TestLLtype(DelTests, LLJitMixin):
- pass
+
+ def test_finalizer(self):
+ mydriver = JitDriver(reds = ['n'], greens = [])
+ class Glob(object):
+ seen = 0
+ glob = Glob()
+ class A(object):
+ def __init__(self):
+ rgc.register_finalizer(self.finalizer)
+ def finalizer(self):
+ glob.seen += 1
+ @dont_look_inside
+ def do_collect():
+ rgc.collect(); rgc.collect()
+ def main(n):
+ glob.seen = 0
+ while n > 0:
+ mydriver.jit_merge_point(n=n)
+ A(); A(); A()
+ n -= 1
+ do_collect()
+ return glob.seen
+ assert main(10) == 30
+ res = self.meta_interp(main, [20])
+ assert res >= 54
+
class TestOOtype(DelTests, OOJitMixin):
def setup_class(cls):
diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -1204,9 +1204,11 @@
v_obj, v_func = hop.spaceop.args
v_obj_addr = hop.genop("cast_ptr_to_adr", [v_obj],
resulttype = llmemory.Address)
+ v_func_addr = hop.genop("cast_ptr_to_adr", [v_func],
+ resulttype = llmemory.Address)
hop.genop("direct_call", [self.register_finalizer_ptr,
self.c_const_gc,
- v_obj_addr, v_func],
+ v_obj_addr, v_func_addr],
resultvar = hop.spaceop.result)
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -384,12 +384,10 @@
r_func, is_method = hop.args_r[0].get_r_implfunc()
assert is_method
c_llfn = r_func.get_unique_llfn()
- v_llfn = hop.genop('cast_ptr_to_adr', [c_llfn],
- resulttype=llmemory.Address)
v_self = hop.genop('cast_pointer', [v_self],
resulttype=base_ptr_lltype())
hop.exception_cannot_occur()
- return hop.genop('gc_register_finalizer', [v_self, v_llfn],
+ return hop.genop('gc_register_finalizer', [v_self, c_llfn],
resulttype=lltype.Void)
class ProgressThroughFinalizerQueueEntry(ExtRegistryEntry):
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -815,6 +815,7 @@
self.llinterpreter.finalizer_queue.append((llobj, llfn))
def op_gc_register_finalizer(self, llptr, llfn):
+ llfn = llmemory.cast_ptr_to_adr(llfn)
if self.heap is llheap:
llobj = llptr._obj
for llobj1, llfn1 in self.llinterpreter.finalizer_queue:
More information about the pypy-commit
mailing list