[pypy-commit] pypy improve-gc-tracing-hooks: (arigo, fijal) whack whack whack, until we get the first test to call the callback
fijal
noreply at buildbot.pypy.org
Mon Oct 20 14:43:30 CEST 2014
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: improve-gc-tracing-hooks
Changeset: r74019:403fe85b70bd
Date: 2014-10-20 14:43 +0200
http://bitbucket.org/pypy/pypy/changeset/403fe85b70bd/
Log: (arigo, fijal) whack whack whack, until we get the first test to
call the callback
diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -70,7 +70,6 @@
member_index,
is_rpython_class,
has_custom_trace,
- get_custom_trace,
fast_path_tracing,
has_gcptr):
self.getfinalizer = getfinalizer
@@ -88,7 +87,6 @@
self.member_index = member_index
self.is_rpython_class = is_rpython_class
self.has_custom_trace = has_custom_trace
- self.get_custom_trace = get_custom_trace
self.fast_path_tracing = fast_path_tracing
self.has_gcptr = has_gcptr
@@ -223,14 +221,7 @@
item += itemlength
length -= 1
if self.has_custom_trace(typeid):
- generator = self.get_custom_trace(typeid)
- item = llmemory.NULL
- while True:
- item = generator(obj, item)
- if not item:
- break
- if self.points_to_valid_gc_object(item):
- callback(item, arg)
+ self.custom_trace_dispatcher(obj, typeid, callback, arg)
_trace_slow_path._annspecialcase_ = 'specialize:arg(2)'
def trace_partial(self, obj, start, stop, callback, arg):
diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py
--- a/rpython/memory/gctypelayout.py
+++ b/rpython/memory/gctypelayout.py
@@ -21,13 +21,9 @@
# It is called with the object as first argument, and the previous
# returned address (or NULL the first time) as the second argument.
FINALIZER_FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
- CUSTOMTRACER_FUNC = lltype.FuncType([llmemory.Address, llmemory.Address],
- llmemory.Address)
FINALIZER = lltype.Ptr(FINALIZER_FUNC)
- CUSTOMTRACER = lltype.Ptr(CUSTOMTRACER_FUNC)
EXTRA = lltype.Struct("type_info_extra",
- ('finalizer', FINALIZER),
- ('customtracer', CUSTOMTRACER))
+ ('finalizer', FINALIZER))
# structure describing the layout of a typeid
TYPE_INFO = lltype.Struct("type_info",
@@ -133,12 +129,6 @@
infobits = self.get(typeid).infobits
return infobits & T_HAS_CUSTOM_TRACE != 0
- def q_get_custom_trace(self, typeid):
- ll_assert(self.q_has_custom_trace(typeid),
- "T_HAS_CUSTOM_TRACE missing")
- typeinfo = self.get(typeid)
- return typeinfo.extra.customtracer
-
def q_fast_path_tracing(self, typeid):
# return True if none of the flags T_HAS_GCPTR_IN_VARSIZE,
# T_IS_GCARRAY_OF_GCPTR or T_HAS_CUSTOM_TRACE is set
@@ -165,7 +155,6 @@
self.q_member_index,
self.q_is_rpython_class,
self.q_has_custom_trace,
- self.q_get_custom_trace,
self.q_fast_path_tracing,
self.q_has_gcptr)
@@ -411,7 +400,9 @@
return None
def initialize_gc_query_function(self, gc):
- return GCData(self.type_info_group).set_query_functions(gc)
+ gcdata = GCData(self.type_info_group)
+ gcdata.set_query_functions(gc)
+ return gcdata
def consider_constant(self, TYPE, value, gc):
if value is not lltype.top_container(value):
diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py
--- a/rpython/memory/gcwrapper.py
+++ b/rpython/memory/gcwrapper.py
@@ -29,7 +29,7 @@
lltype2vtable,
self.llinterp)
self.get_type_id = layoutbuilder.get_type_id
- layoutbuilder.initialize_gc_query_function(self.gc)
+ gcdata = layoutbuilder.initialize_gc_query_function(self.gc)
constants = collect_constants(flowgraphs)
for obj in constants:
@@ -38,8 +38,27 @@
self.constantroots = layoutbuilder.addresses_of_static_ptrs
self.constantrootsnongc = layoutbuilder.addresses_of_static_ptrs_in_nongc
+ self.prepare_custom_trace_funcs(gcdata)
self._all_prebuilt_gc = layoutbuilder.all_prebuilt_gc
+ def prepare_custom_trace_funcs(self, gcdata):
+ custom_trace_funcs = self.llinterp.typer.custom_trace_funcs
+
+ 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)
+ 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)
+
+ self.gc.custom_trace_dispatcher = custom_trace
+
# ____________________________________________________________
#
# Interface for the llinterp
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
@@ -6,7 +6,7 @@
from rpython.rtyper.test.test_llinterp import get_interpreter
from rpython.rtyper.lltypesystem import lltype
from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, keepalive_until_here
from rpython.rlib.objectmodel import compute_unique_id
from rpython.rlib import rgc
from rpython.rlib.rstring import StringBuilder
@@ -762,6 +762,22 @@
assert rgc.get_gcflag_extra(a1) == False
assert rgc.get_gcflag_extra(a2) == False
self.interpret(fn, [])
+
+ def test_register_custom_trace_hook(self):
+ S = lltype.GcStruct('S', ('x', lltype.Signed))
+ called = []
+
+ def trace_hook(obj, callback, arg):
+ called.append("called")
+
+ def f():
+ rgc.register_custom_trace_hook(S, trace_hook)
+ s = lltype.malloc(S)
+ rgc.collect()
+ keepalive_until_here(s)
+
+ self.interpret(f, [])
+ assert called # not empty, can contain more than one item
from rpython.rlib.objectmodel import UnboxedValue
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
@@ -14,7 +14,7 @@
from rpython.conftest import option
from rpython.rlib.rstring import StringBuilder
from rpython.rlib.rarithmetic import LONG_BIT
-import pdb
+
WORD = LONG_BIT // 8
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -550,14 +550,14 @@
def lltype_is_gc(TP):
return getattr(getattr(TP, "TO", None), "_gckind", "?") == 'gc'
-def register_custom_gc_trace(TP, func):
+def register_custom_trace_hook(TP, 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
"""
class RegisterGcTraceEntry(ExtRegistryEntry):
- _about_ = register_custom_gc_trace
+ _about_ = register_custom_trace_hook
def compute_result_annotation(self, *args_s):
pass
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
@@ -229,14 +229,14 @@
n = rgc.get_rpy_memory_usage(rgc.cast_instance_to_gcref(x1))
assert n >= 8 and n <= 64
-def test_register_custom_gc_trace():
+def test_register_custom_trace_hook():
TP = lltype.GcStruct('X')
def trace_func():
xxx # should not be annotated here
def f():
- rgc.register_custom_gc_trace(TP, trace_func)
+ rgc.register_custom_trace_hook(TP, trace_func)
t, typer, graph = gengraph(f, [])
More information about the pypy-commit
mailing list