Author: Maciej Fijalkowski <[email protected]>
Branch: imrpove-custom-gc-tracing
Changeset: r60192:b103c0c9fec5
Date: 2013-01-19 11:32 +0200
http://bitbucket.org/pypy/pypy/changeset/b103c0c9fec5/
Log: work in progress not sure where to go from here
diff --git a/pypy/rpython/lltypesystem/lloperation.py
b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -500,6 +500,7 @@
'gc_gcflag_extra' : LLOp(),
'gc_add_memory_pressure': LLOp(),
'gc_set_extra_threshold': LLOp(canrun=True, canmallocgc=True),
+ 'gc_call_custom_trace': LLOp(canrun=True), # cannot malloc
# ------- JIT & GC interaction, only for some GCs ----------
diff --git a/pypy/rpython/lltypesystem/opimpl.py
b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -647,6 +647,9 @@
def op_gc_set_extra_threshold(threshold):
pass
+def op_gc_call_custom_trace(gc, *args):
+ gc._call_custom_trace(*args)
+
def op_shrink_array(array, smallersize):
return False
diff --git a/pypy/rpython/memory/gc/base.py b/pypy/rpython/memory/gc/base.py
--- a/pypy/rpython/memory/gc/base.py
+++ b/pypy/rpython/memory/gc/base.py
@@ -6,6 +6,7 @@
from pypy.rpython.memory.support import get_address_stack, get_address_deque
from pypy.rpython.memory.support import AddressDict, null_address_dict
from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage
+from pypy.rlib.objectmodel import specialize
TYPEID_MAP = lltype.GcStruct('TYPEID_MAP', ('count', lltype.Signed),
('size', lltype.Signed),
@@ -210,11 +211,13 @@
trace._annspecialcase_ = 'specialize:arg(2)'
def _call_custom_trace(self, obj, typeid, callback, arg):
- def wrapper(item, arg):
- if self.is_valid_gc_object(item):
- callback(item, arg)
-
- self.custom_trace_funcs[typeid.index](obj, wrapper, arg)
+ #def wrapper(item, arg):
+ # if self.is_valid_gc_object(item):
+ # callback(item, arg)
+
+ for obj_typeid, func in self.custom_trace_funcs:
+ if typeid == obj_typeid:
+ func(obj, callback, arg)
def _trace_slow_path(self, obj, callback, arg):
typeid = self.get_type_id(obj)
@@ -233,7 +236,10 @@
item += itemlength
length -= 1
if self.has_custom_trace(typeid):
- self._call_custom_trace(obj, typeid, callback, arg)
+ # an obscure hack to flow those only when we
+ # actually have all typeids
+ llop.gc_call_custom_trace(lltype.Void, self, obj, typeid, callback,
+ arg)
_trace_slow_path._annspecialcase_ = 'specialize:arg(2)'
def trace_partial(self, obj, start, stop, callback, arg):
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
@@ -888,6 +888,11 @@
source_addr, dest_addr] + op.args[2:],
resultvar=op.result)
+ def gct_gc_call_custom_trace(self, hop):
+ args = hop.spaceop.args
+ args[3].concretetype
+ hop.genop('direct_call', [])
+
def gct_weakref_create(self, hop):
op = hop.spaceop
@@ -1216,6 +1221,7 @@
else:
lltype2vtable = None
self.translator = translator
+ self.custom_trace_funcs = []
super(TransformerLayoutBuilder, self).__init__(GCClass, lltype2vtable)
def has_finalizer(self, TYPE):
@@ -1229,7 +1235,7 @@
def has_custom_trace(self, TYPE):
rtti = get_rtti(TYPE)
- return rtti is not None and getattr(rtti._obj, 'custom_trace_funcptr',
+ return rtti is not None and getattr(rtti._obj, 'custom_trace_func',
None)
def make_finalizer_funcptr_for_type(self, TYPE):
@@ -1249,16 +1255,14 @@
light = not
FinalizerAnalyzer(self.translator).analyze_light_finalizer(g)
return fptr, light
- def make_custom_trace_funcptr_for_type(self, TYPE):
+ def get_custom_trace_func(self, TYPE):
if not self.has_custom_trace(TYPE):
return None
rtti = get_rtti(TYPE)
- fptr = rtti._obj.custom_trace_funcptr
- if not hasattr(fptr._obj, 'graph'):
- ll_func = fptr._obj._callable
- fptr = self.transformer.annotate_finalizer(ll_func,
- [llmemory.Address, llmemory.Address], llmemory.Address)
- return fptr
+ return rtti._obj.custom_trace_func
+
+ def record_custom_trace(self, typeid, custom_trace_func):
+ self.custom_trace_funcs.append((typeid, custom_trace_func))
def gen_zero_gc_pointers(TYPE, v, llops, previous_steps=None):
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
@@ -103,6 +103,7 @@
self.minimalgctransformer = self.MinimalGCTransformer(self)
else:
self.minimalgctransformer = None
+ self.call_custom_trace_cache = {}
def get_lltype_of_exception_value(self):
exceptiondata = self.translator.rtyper.getexceptiondata()
diff --git a/pypy/rpython/memory/gctypelayout.py
b/pypy/rpython/memory/gctypelayout.py
--- a/pypy/rpython/memory/gctypelayout.py
+++ b/pypy/rpython/memory/gctypelayout.py
@@ -183,7 +183,7 @@
"invalid type_id")
-def encode_type_shape(builder, info, TYPE, index):
+def encode_type_shape(builder, info, TYPE, index, type_id):
"""Encode the shape of the TYPE into the TYPE_INFO structure 'info'."""
offsets = offsets_to_gc_pointers(TYPE)
infobits = index
@@ -202,7 +202,7 @@
custom_trace_func = builder.get_custom_trace_func(TYPE)
if custom_trace_func is not None:
infobits |= T_HAS_CUSTOM_TRACE
- builder.record_custom_trace(index, custom_trace_func)
+ builder.record_custom_trace(type_id, custom_trace_func)
#
if not TYPE._is_varsize():
info.fixedsize = llarena.round_up_for_allocation(
@@ -296,9 +296,10 @@
info = fullinfo.header
type_id = self.type_info_group.add_member(fullinfo)
if self.can_encode_type_shape:
- encode_type_shape(self, info, TYPE, type_id.index)
+ encode_type_shape(self, info, TYPE, type_id.index, type_id)
else:
- self._pending_type_shapes.append((info, TYPE, type_id.index))
+ self._pending_type_shapes.append((info, TYPE, type_id.index,
+ type_id))
# store it
self.id_of_type[TYPE] = type_id
self.add_vtable_after_typeinfo(TYPE)
@@ -341,8 +342,8 @@
def encode_type_shapes_now(self):
if not self.can_encode_type_shape:
self.can_encode_type_shape = True
- for info, TYPE, index in self._pending_type_shapes:
- encode_type_shape(self, info, TYPE, index)
+ for info, TYPE, index, type_id in self._pending_type_shapes:
+ encode_type_shape(self, info, TYPE, index, type_id)
del self._pending_type_shapes
def delay_encoding(self):
diff --git a/pypy/rpython/memory/gcwrapper.py b/pypy/rpython/memory/gcwrapper.py
--- a/pypy/rpython/memory/gcwrapper.py
+++ b/pypy/rpython/memory/gcwrapper.py
@@ -26,7 +26,7 @@
def prepare_graphs(self, flowgraphs):
lltype2vtable = self.llinterp.typer.lltype2vtable
# only valid for direct layout builder
- self.gc.custom_trace_funcs = {}
+ self.gc.custom_trace_funcs = []
layoutbuilder = DirectRunLayoutBuilder(self.gc.__class__,
lltype2vtable,
self.llinterp,
@@ -232,7 +232,7 @@
return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer),
light
def record_custom_trace(self, tid, custom_trace_func):
- self.custom_trace_funcs[tid] = custom_trace_func
+ self.custom_trace_funcs.append((tid, custom_trace_func))
def get_custom_trace_func(self, TYPE):
from pypy.rpython.memory.gctransform.support import get_rtti
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
@@ -382,21 +382,13 @@
assert 160 <= res <= 165
def define_custom_trace(cls):
- from pypy.rpython.annlowlevel import llhelper
- from pypy.rpython.lltypesystem import llmemory
- #
+
S = lltype.GcStruct('S', ('x', llmemory.Address), rtti=True)
T = lltype.GcStruct('T', ('z', lltype.Signed))
offset_of_x = llmemory.offsetof(S, 'x')
- def customtrace(obj, prev):
- if not prev:
- return obj + offset_of_x
- else:
- return llmemory.NULL
- CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address],
- llmemory.Address)
- customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace)
- lltype.attachRuntimeTypeInfo(S, customtraceptr=customtraceptr)
+ def customtrace(obj, callback, arg):
+ callback(obj + offset_of_x, arg)
+ lltype.attachRuntimeTypeInfo(S, custom_trace_func=customtrace)
#
def setup():
s1 = lltype.malloc(S)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit