[pypy-svn] r49683 - pypy/branch/pypy-gc-traceopt/rpython/memory/gc

arigo at codespeak.net arigo at codespeak.net
Wed Dec 12 21:54:38 CET 2007


Author: arigo
Date: Wed Dec 12 21:54:38 2007
New Revision: 49683

Added:
   pypy/branch/pypy-gc-traceopt/rpython/memory/gc/traceopt.py   (contents, props changed)
Log:
Forgot this file.


Added: pypy/branch/pypy-gc-traceopt/rpython/memory/gc/traceopt.py
==============================================================================
--- (empty file)
+++ pypy/branch/pypy-gc-traceopt/rpython/memory/gc/traceopt.py	Wed Dec 12 21:54:38 2007
@@ -0,0 +1,92 @@
+from pypy.rlib.unroll import unrolling_iterable
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.memory.gctypelayout import offsets_to_gc_pointers
+
+# ____________________________________________________________
+
+TRACEOPT_INDEXES = lltype.Array(lltype.Char, hints={'nolength': True})
+
+def set_typeid_count(gc, count):
+    print 'SET_TYPEID_COUNT', count
+    gc.traceopt_index = lltype.malloc(TRACEOPT_INDEXES, count, flavor='raw')
+    i = 0
+    while i < count:
+        gc.traceopt_index[i] = chr(0)
+        i += 1
+
+def enumerate_lltypes():
+    for n in range(32):
+        fields = []
+        for i in range(5):
+            if n & (1<<i):
+                FIELDTYPE = llmemory.GCREF
+            else:
+                FIELDTYPE = llmemory.Address
+            fields.append(('p%d' % i, FIELDTYPE))
+        yield lltype.GcStruct('dummy', *fields)
+    #yield lltype.GcArray(llmemory.GCREF)
+
+def build_common_shape_fn(TYPE):
+    assert isinstance(TYPE, lltype.GcStruct)
+    assert not TYPE._is_varsize()
+    offsets = offsets_to_gc_pointers(TYPE)
+    unroll_offsets = unrolling_iterable(offsets)
+
+    def tracer(gc, obj, callback):
+        for offset in unroll_offsets:
+            callback(gc, obj + offset)
+    tracer._annspecialcase_ = 'specialize:arg(2)'
+    tracer._inline_ = True
+
+    def compatible_shape(gc, typeid):
+        if gc.is_varsize(typeid):
+            return False
+        cur_offsets = gc.offsets_to_gc_pointers(typeid)
+        if len(cur_offsets) != len(offsets):
+            return False
+        i = 0
+        while i < len(offsets):
+            if cur_offsets[i] != offsets[i]:
+                return False
+            i += 1
+        return True
+    compatible_shape._inline_ = True
+
+    return compatible_shape, tracer
+
+def get_common_shape_fns():
+    # index 0: not decided yet
+    # index 255: reserved for the unoptimized case
+    checkers = {}
+    tracers = {}
+    all_lltypes = list(enumerate_lltypes())
+    assert len(all_lltypes) <= 254
+    for idx, TYPE in enumerate(all_lltypes):
+        checker, tracer = build_common_shape_fn(TYPE)
+        checkers[idx+1] = checker
+        tracers[idx+1] = tracer
+    return checkers, tracers
+
+common_shape_checkers, common_shape_tracers = get_common_shape_fns()
+unroll_common_shape_checkers= unrolling_iterable(common_shape_checkers.items())
+unroll_common_shape_tracers = unrolling_iterable(common_shape_tracers.items())
+
+def optimized_trace(gc, obj, typeid, callback):
+    shapeindex = ord(gc.traceopt_index[typeid])
+    for idx, tracer in unroll_common_shape_tracers:
+        if shapeindex == idx:
+            tracer(gc, obj, callback)
+            return True
+    if shapeindex == 0:
+        find_common_shape(gc, typeid)
+    return False
+optimized_trace._annspecialcase_ = 'specialize:arg(3)'
+
+def find_common_shape(gc, typeid):
+    shapeindex = 255
+    for idx, checker in unroll_common_shape_checkers:
+        if checker(gc, typeid):
+            shapeindex = idx
+            break
+    print "find_common_shape:", typeid, "is shape", shapeindex
+    gc.traceopt_index[typeid] = chr(shapeindex)



More information about the Pypy-commit mailing list