Author: Armin Rigo <[email protected]>
Branch: improve-gc-tracing-hooks
Changeset: r74030:00d7923edeea
Date: 2014-10-21 13:33 +0200
http://bitbucket.org/pypy/pypy/changeset/00d7923edeea/
Log: Shuffle shuffle shuffle until test_transformed_gc is happy
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
@@ -5,7 +5,7 @@
from rpython.rlib.unroll import unrolling_iterable
from rpython.rtyper import rmodel, annlowlevel
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, llgroup
-from rpython.rtyper.lltypesystem.lloperation import LL_OPERATIONS
+from rpython.rtyper.lltypesystem.lloperation import LL_OPERATIONS, llop
from rpython.memory import gctypelayout
from rpython.memory.gctransform.log import log
from rpython.memory.gctransform.support import get_rtti, ll_call_destructor
@@ -174,8 +174,6 @@
self.malloc_fnptr_cache = {}
gcdata.gc = GCClass(translator.config.translation, **GC_PARAMS)
- self.create_custom_trace_funcs(gcdata.gc,
- translator.rtyper.custom_trace_funcs)
root_walker = self.build_root_walker()
root_walker.finished_minor_collection_func = finished_minor_collection
self.root_walker = root_walker
@@ -243,6 +241,8 @@
root_walker.need_stacklet_support(self, getfn)
self.layoutbuilder.encode_type_shapes_now()
+ self.create_custom_trace_funcs(gcdata.gc,
+ translator.rtyper.custom_trace_funcs)
annhelper.finish() # at this point, annotate all mix-level helpers
annhelper.backend_optimize()
@@ -498,19 +498,21 @@
custom_trace_funcs_unrolled = unrolling_iterable(
[(self.get_type_id(TP), func) for TP, func in custom_trace_funcs])
- @specialize.arg(3)
- def custom_trace_dispatcher(self, obj, typeid, callback, arg):
+ @specialize.arg(2)
+ def custom_trace_dispatcher(obj, typeid, callback, arg):
for type_id_exp, func in custom_trace_funcs_unrolled:
- if typeid == type_id_exp:
- func(obj, callback, arg)
+ if (llop.combine_ushort(lltype.Signed, typeid, 0) ==
+ llop.combine_ushort(lltype.Signed, type_id_exp, 0)):
+ func(gc, obj, callback, arg)
return
else:
assert False
- gc.__class__.custom_trace_dispatcher = custom_trace_dispatcher
+ gc.custom_trace_dispatcher = custom_trace_dispatcher
for TP, func in custom_trace_funcs:
- specialize.arg(1)(func)
+ self.gcdata._has_got_custom_trace(self.get_type_id(TP))
+ specialize.arg(2)(func)
def consider_constant(self, TYPE, value):
self.layoutbuilder.consider_constant(TYPE, value, self.gcdata.gc)
diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py
--- a/rpython/memory/gctypelayout.py
+++ b/rpython/memory/gctypelayout.py
@@ -151,6 +151,10 @@
self.q_fast_path_tracing,
self.q_has_gcptr)
+ def _has_got_custom_trace(self, typeid):
+ type_info = self.get(typeid)
+ type_info.infobits |= (T_HAS_CUSTOM_TRACE | T_HAS_GCPTR)
+
# the lowest 16bits are used to store group member index
T_MEMBER_INDEX = 0xffff
diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py
--- a/rpython/memory/gcwrapper.py
+++ b/rpython/memory/gcwrapper.py
@@ -47,15 +47,13 @@
def custom_trace(obj, typeid, callback, arg):
for TP, func in custom_trace_funcs:
if typeid == self.get_type_id(TP):
- func(obj, callback, arg)
+ func(self.gc, obj, callback, arg)
return
else:
assert False
for TP, func in custom_trace_funcs:
- type_info = gcdata.get(self.get_type_id(TP))
- type_info.infobits |= (gctypelayout.T_HAS_CUSTOM_TRACE |
- gctypelayout.T_HAS_GCPTR)
+ gcdata._has_got_custom_trace(self.get_type_id(TP))
self.gc.custom_trace_dispatcher = custom_trace
diff --git a/rpython/memory/test/gc_test_base.py
b/rpython/memory/test/gc_test_base.py
--- a/rpython/memory/test/gc_test_base.py
+++ b/rpython/memory/test/gc_test_base.py
@@ -244,12 +244,14 @@
('y', llmemory.Address))
T = lltype.GcStruct('T', ('z', lltype.Signed))
offset_of_x = llmemory.offsetof(S, 'x')
- def customtrace(obj, callback, arg):
- callback(obj + offset_of_x, arg)
+ def customtrace(gc, obj, callback, arg):
+ if gc.is_valid_gc_object((obj + offset_of_x).address[0]):
+ callback(obj + offset_of_x, arg)
+ lambda_customtrace = lambda: customtrace
#
for attrname in ['x', 'y']:
def setup():
- rgc.register_custom_trace_hook(S, customtrace)
+ rgc.register_custom_trace_hook(S, lambda_customtrace)
s1 = lltype.malloc(S)
tx = lltype.malloc(T)
tx.z = 42
@@ -760,11 +762,12 @@
S = lltype.GcStruct('S', ('x', lltype.Signed))
called = []
- def trace_hook(obj, callback, arg):
+ def trace_hook(gc, obj, callback, arg):
called.append("called")
+ lambda_trace_hook = lambda: trace_hook
def f():
- rgc.register_custom_trace_hook(S, trace_hook)
+ rgc.register_custom_trace_hook(S, lambda_trace_hook)
s = lltype.malloc(S)
rgc.collect()
keepalive_until_here(s)
diff --git a/rpython/memory/test/test_transformed_gc.py
b/rpython/memory/test/test_transformed_gc.py
--- a/rpython/memory/test/test_transformed_gc.py
+++ b/rpython/memory/test/test_transformed_gc.py
@@ -389,15 +389,17 @@
S = lltype.GcStruct('S', ('x', llmemory.Address))
T = lltype.GcStruct('T', ('z', lltype.Signed))
offset_of_x = llmemory.offsetof(S, 'x')
- def customtrace(obj, callback, arg):
- callback(obj + offset_of_x, arg)
+ def customtrace(gc, obj, callback, arg):
+ if gc.is_valid_gc_object((obj + offset_of_x).address[0]):
+ callback(obj + offset_of_x, arg)
+ lambda_customtrace = lambda: customtrace
#
def setup():
- rgc.register_custom_trace_hook(S, customtrace)
- s1 = lltype.malloc(S)
+ rgc.register_custom_trace_hook(S, lambda_customtrace)
tx = lltype.malloc(T)
tx.z = 4243
+ s1 = lltype.malloc(S)
s1.x = llmemory.cast_ptr_to_adr(tx)
return s1
def f():
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -550,10 +550,11 @@
def lltype_is_gc(TP):
return getattr(getattr(TP, "TO", None), "_gckind", "?") == 'gc'
-def register_custom_trace_hook(TP, func):
+def register_custom_trace_hook(TP, lambda_func):
""" This function does not do anything, but called from any annotated
place, will tell that "func" is used to trace GC roots inside any instance
- of the type TP
+ of the type TP. The func must be specified as "lambda: func" in this
+ call, for internal reasons.
"""
class RegisterGcTraceEntry(ExtRegistryEntry):
@@ -564,6 +565,6 @@
def specialize_call(self, hop):
TP = hop.args_s[0].const
- func = hop.args_s[1].const
+ lambda_func = hop.args_s[1].const
hop.exception_cannot_occur()
- hop.rtyper.custom_trace_funcs.append((TP, func))
+ hop.rtyper.custom_trace_funcs.append((TP, lambda_func()))
diff --git a/rpython/rlib/test/test_rgc.py b/rpython/rlib/test/test_rgc.py
--- a/rpython/rlib/test/test_rgc.py
+++ b/rpython/rlib/test/test_rgc.py
@@ -234,9 +234,10 @@
def trace_func():
xxx # should not be annotated here
+ lambda_trace_func = lambda: trace_func
def f():
- rgc.register_custom_trace_hook(TP, trace_func)
+ rgc.register_custom_trace_hook(TP, lambda_trace_func)
t, typer, graph = gengraph(f, [])
diff --git a/rpython/rtyper/lltypesystem/opimpl.py
b/rpython/rtyper/lltypesystem/opimpl.py
--- a/rpython/rtyper/lltypesystem/opimpl.py
+++ b/rpython/rtyper/lltypesystem/opimpl.py
@@ -82,13 +82,11 @@
else:
def op_function(x, y):
if not isinstance(x, argtype):
- if not (isinstance(x, AddressAsInt) and argtype is int):
- raise TypeError("%r arg 1 must be %s, got %r instead"%
(
- fullopname, typname, type(x).__name__))
+ raise TypeError("%r arg 1 must be %s, got %r instead"% (
+ fullopname, typname, type(x).__name__))
if not isinstance(y, argtype):
- if not (isinstance(y, AddressAsInt) and argtype is int):
- raise TypeError("%r arg 2 must be %s, got %r instead"%
(
- fullopname, typname, type(y).__name__))
+ raise TypeError("%r arg 2 must be %s, got %r instead"% (
+ fullopname, typname, type(y).__name__))
return adjust_result(func(x, y))
return func_with_new_name(op_function, 'op_' + fullopname)
@@ -104,6 +102,19 @@
lltype.typeOf(adr),))
+def op_int_eq(x, y):
+ if not isinstance(x, (int, long)):
+ from rpython.rtyper.lltypesystem import llgroup
+ assert isinstance(x, llgroup.CombinedSymbolic), (
+ "'int_eq' arg 1 must be int-like, got %r instead" % (
+ type(x).__name__,))
+ if not isinstance(y, (int, long)):
+ from rpython.rtyper.lltypesystem import llgroup
+ assert isinstance(y, llgroup.CombinedSymbolic), (
+ "'int_eq' arg 2 must be int-like, got %r instead" % (
+ type(y).__name__,))
+ return x == y
+
def op_ptr_eq(ptr1, ptr2):
checkptr(ptr1)
checkptr(ptr2)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit