Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60196:d6f5e379ab27
Date: 2013-01-19 12:46 +0200
http://bitbucket.org/pypy/pypy/changeset/d6f5e379ab27/

Log:    implement a custom tracer abomination

diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -143,7 +143,6 @@
     kind                  = 'boehm'
     moving_gc             = False
     round_up              = False
-    gcrootmap             = None
     write_barrier_descr   = None
     fielddescr_tid        = None
     str_type_id           = 0
@@ -300,8 +299,9 @@
         else:
             assert self.translate_support_code,"required with the framework GC"
             self._check_valid_gc()
-            self._make_gcrootmap()
             self._make_layoutbuilder()
+            self.gcrootfindername = 
self.gcdescr.config.translation.gcrootfinder
+            assert self.gcrootfindername in ['asmgcc', 'shadowstack']
             self._setup_gcclass()
             self._setup_tid()
         self._setup_write_barrier()
@@ -322,17 +322,6 @@
             raise NotImplementedError("--gc=%s not implemented with the JIT" %
                                       (self.gcdescr.config.translation.gc,))
 
-    def _make_gcrootmap(self):
-        # to find roots in the assembler, make a GcRootMap
-        name = self.gcdescr.config.translation.gcrootfinder
-        try:
-            cls = globals()['GcRootMap_' + name]
-        except KeyError:
-            raise NotImplementedError("--gcrootfinder=%s not implemented"
-                                      " with the JIT" % (name,))
-        gcrootmap = cls(self.gcdescr)
-        self.gcrootmap = gcrootmap
-
     def _make_layoutbuilder(self):
         # make a TransformerLayoutBuilder and save it on the translator
         # where it can be fished and reused by the FrameworkGCTransformer
@@ -340,8 +329,8 @@
         translator = self.translator
         self.layoutbuilder = framework.TransformerLayoutBuilder(translator)
         self.layoutbuilder.delay_encoding()
+        # XXX this can probably die horrible death
         translator._jit2gc = {'layoutbuilder': self.layoutbuilder}
-        self.gcrootmap.add_jit2gc_hooks(translator._jit2gc)
 
     def _setup_gcclass(self):
         from pypy.rpython.memory.gcheader import GCHeaderBuilder
@@ -492,7 +481,7 @@
         return rffi.cast(lltype.Signed, nurs_top_addr)
 
     def initialize(self):
-        self.gcrootmap.initialize()
+        pass
 
     def init_size_descr(self, S, descr):
         if self.layoutbuilder is not None:
diff --git a/pypy/jit/backend/llsupport/jitframe.py 
b/pypy/jit/backend/llsupport/jitframe.py
--- a/pypy/jit/backend/llsupport/jitframe.py
+++ b/pypy/jit/backend/llsupport/jitframe.py
@@ -1,4 +1,8 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.annlowlevel import llhelper
+from pypy.rlib.objectmodel import specialize
+
+STATICSIZE = 0 # patch from the assembler backend
 
 # this is an info that only depends on the assembler executed, copied from
 # compiled loop token (in fact we could use this as a compiled loop token
@@ -15,7 +19,6 @@
     # gcindexlist is a list of indexes of GC ptrs
     # in the actual array jf_frame of JITFRAME
     ('jfi_gcmap', lltype.Ptr(GCMAP)),
-    ('counter', lltype.Signed),
 )
 
 NULLFRAMEINFO = lltype.nullptr(JITFRAMEINFO)
@@ -58,6 +61,8 @@
     # RPython code that finishes the function with an exception, the
     # exception is not stored there, but is simply kept as a variable there)
     ('jf_guard_exc', llmemory.GCREF),
+    # absolutely useless field used to make up for tracing hooks 
inflexibilities
+    ('jf_gc_trace_state', lltype.Signed),
     # the actual frame
     ('jf_frame', lltype.Array(lltype.Signed)),
     # note that we keep length field, because it's crucial to have the data
@@ -65,7 +70,66 @@
     adtmeths = {
         'allocate': jitframe_allocate,
         'copy': jitframe_copy,
-    }
+    },
+    rtti = True,
 )
 
[email protected]()
+def getofs(name):
+    return llmemory.offsetof(JITFRAME, name)
+
+GCMAPLENGTHOFS = llmemory.arraylengthoffset(GCMAP)
+GCMAPBASEOFS = llmemory.itemoffsetof(GCMAP, 0)
+BASEITEMOFS = llmemory.itemoffsetof(JITFRAME.jf_frame, 0)
+SIGN_SIZE = llmemory.sizeof(lltype.Signed)
+
+def jitframe_trace(obj_addr, prev):
+    if prev == llmemory.NULL:
+        (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 0
+        return obj_addr + getofs('jf_frame_info')
+    fld = (obj_addr + getofs('jf_gc_trace_state')).signed[0]
+    state = fld & 0xff
+    no = fld >> 8
+    if state == 0:
+        (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 1
+        return obj_addr + getofs('jf_descr')
+    elif state == 1:
+        (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 2
+        return obj_addr + getofs('jf_force_descr')
+    elif state == 2:
+        (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 3
+        return obj_addr + getofs('jf_gcmap')
+    elif state == 3:
+        (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 4
+        return obj_addr + getofs('jf_savedata')
+    elif state == 4:
+        (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 5
+        return obj_addr + getofs('jf_guard_exc')
+    elif state == 5:
+        # bit pattern
+        gcpat = (obj_addr + getofs('jf_gcpattern')).signed[0]
+        while no < STATICSIZE and gcpat & (1 << no) == 0:
+            no += 1
+        if no != STATICSIZE:
+            newstate = 5 | ((no + 1) << 8)
+            (obj_addr + getofs('jf_gc_trace_state')).signed[0] = newstate
+            return obj_addr + getofs('jf_frame') + BASEITEMOFS + SIGN_SIZE * no
+        state = 6
+        no = 0
+    assert state == 6
+    gcmap = (obj_addr + getofs('jf_gcmap')).address[0]
+    gcmaplen = (gcmap + GCMAPLENGTHOFS).signed[0]
+    if no >= gcmaplen:
+        return llmemory.NULL
+    index = (gcmap + GCMAPBASEOFS + SIGN_SIZE * no).signed[0] + STATICSIZE
+    newstate = 6 | ((no + 1) << 8)
+    (obj_addr + getofs('jf_gc_trace_state')).signed[0] = newstate
+    return obj_addr + getofs('jf_frame') + BASEITEMOFS + SIGN_SIZE * index
+
+CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address],
+                                  llmemory.Address)
+jitframe_trace_ptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), jitframe_trace)
+
+lltype.attachRuntimeTypeInfo(JITFRAME, customtraceptr=jitframe_trace_ptr)
+
 JITFRAMEPTR = lltype.Ptr(JITFRAME)
diff --git a/pypy/jit/backend/llsupport/test/test_gc.py 
b/pypy/jit/backend/llsupport/test/test_gc.py
--- a/pypy/jit/backend/llsupport/test/test_gc.py
+++ b/pypy/jit/backend/llsupport/test/test_gc.py
@@ -1,20 +1,16 @@
-import random
-from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr
+from pypy.rpython.lltypesystem import lltype, llmemory, rstr
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rpython.annlowlevel import llhelper
-from pypy.jit.backend.llsupport.descr import *
-from pypy.jit.backend.llsupport.gc import *
+from pypy.jit.backend.llsupport import jitframe, gc, descr
 from pypy.jit.backend.llsupport import symbolic
 from pypy.jit.metainterp.gc import get_description
 from pypy.jit.metainterp.history import BoxPtr, BoxInt, ConstPtr
-from pypy.jit.metainterp.resoperation import get_deep_immutable_oplist
-from pypy.jit.tool.oparser import parse
-from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
-from pypy.jit.metainterp.optimizeopt.util import equaloplists
+from pypy.jit.metainterp.resoperation import get_deep_immutable_oplist, rop,\
+     ResOperation
 from pypy.rlib.rarithmetic import is_valid_int
 
 def test_boehm():
-    gc_ll_descr = GcLLDescr_boehm(None, None, None)
+    gc_ll_descr = gc.GcLLDescr_boehm(None, None, None)
     #
     record = []
     prev_malloc_fn_ptr = gc_ll_descr.malloc_fn_ptr
@@ -26,13 +22,13 @@
     #
     # ---------- gc_malloc ----------
     S = lltype.GcStruct('S', ('x', lltype.Signed))
-    sizedescr = get_size_descr(gc_ll_descr, S)
+    sizedescr = descr.get_size_descr(gc_ll_descr, S)
     p = gc_ll_descr.gc_malloc(sizedescr)
     assert record == [(sizedescr.size, p)]
     del record[:]
     # ---------- gc_malloc_array ----------
     A = lltype.GcArray(lltype.Signed)
-    arraydescr = get_array_descr(gc_ll_descr, A)
+    arraydescr = descr.get_array_descr(gc_ll_descr, A)
     p = gc_ll_descr.gc_malloc_array(10, arraydescr)
     assert record == [(arraydescr.basesize +
                        10 * arraydescr.itemsize, p)]
@@ -52,199 +48,6 @@
 # ____________________________________________________________
 
 
-class TestGcRootMapAsmGcc:
-
-    def test_make_shapes(self):
-        def frame_pos(n):
-            return -4*(4+n)
-        gcrootmap = GcRootMap_asmgcc()
-        gcrootmap.is_64_bit = False
-        num1 = frame_pos(-5)
-        num1a = num1|2
-        num2 = frame_pos(55)
-        num2a = ((-num2|3) >> 7) | 128
-        num2b = (-num2|3) & 127
-        shape = gcrootmap.get_basic_shape()
-        gcrootmap.add_frame_offset(shape, num1)
-        gcrootmap.add_frame_offset(shape, num2)
-        assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a])
-        gcrootmap.add_callee_save_reg(shape, 1)
-        assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a,
-                                  4])
-        gcrootmap.add_callee_save_reg(shape, 2)
-        assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a,
-                                  4, 8])
-        gcrootmap.add_callee_save_reg(shape, 3)
-        assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a,
-                                  4, 8, 12])
-        gcrootmap.add_callee_save_reg(shape, 4)
-        assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a,
-                                  4, 8, 12, 16])
-
-    def test_compress_callshape(self):
-        class FakeDataBlockWrapper:
-            def malloc_aligned(self, size, alignment):
-                assert alignment == 1    # here
-                assert size == 4
-                return rffi.cast(lltype.Signed, p)
-        datablockwrapper = FakeDataBlockWrapper()
-        p = lltype.malloc(rffi.CArray(lltype.Char), 4, immortal=True)
-        gcrootmap = GcRootMap_asmgcc()
-        shape = ['a', 'b', 'c', 'd']
-        gcrootmap.compress_callshape(shape, datablockwrapper)
-        assert p[0] == 'd'
-        assert p[1] == 'c'
-        assert p[2] == 'b'
-        assert p[3] == 'a'
-
-    def test_put_basic(self):
-        gcrootmap = GcRootMap_asmgcc()
-        retaddr = 1234567890
-        shapeaddr = 51627384
-        gcrootmap.put(retaddr, shapeaddr)
-        assert gcrootmap._gcmap[0] == retaddr
-        assert gcrootmap._gcmap[1] == shapeaddr
-        p = rffi.cast(rffi.SIGNEDP, gcrootmap.gcmapstart())
-        assert p[0] == retaddr
-        assert (gcrootmap.gcmapend() ==
-                gcrootmap.gcmapstart() + rffi.sizeof(lltype.Signed) * 2)
-
-    def test_put_resize(self):
-        # the same as before, but enough times to trigger a few resizes
-        gcrootmap = GcRootMap_asmgcc()
-        for i in range(700):
-            shapeaddr = i * 100 + 1
-            retaddr = 123456789 + i
-            gcrootmap.put(retaddr, shapeaddr)
-        for i in range(700):
-            assert gcrootmap._gcmap[i*2+0] == 123456789 + i
-            assert gcrootmap._gcmap[i*2+1] == i * 100 + 1
-
-    def test_remove_nulls(self):
-        expected = []
-        def check():
-            assert gcrootmap._gcmap_curlength == len(expected) * 2
-            for i, (a, b) in enumerate(expected):
-                assert gcrootmap._gcmap[i*2] == a
-                assert gcrootmap._gcmap[i*2+1] == b
-        #
-        gcrootmap = GcRootMap_asmgcc()
-        for i in range(700):
-            shapeaddr = i * 100       # 0 if i == 0
-            retaddr = 123456789 + i
-            gcrootmap.put(retaddr, shapeaddr)
-            if shapeaddr != 0:
-                expected.append((retaddr, shapeaddr))
-        # at the first resize, the 0 should be removed
-        check()
-        for repeat in range(10):
-            # now clear up half the entries
-            assert len(expected) == 699
-            for i in range(0, len(expected), 2):
-                gcrootmap._gcmap[i*2+1] = 0
-                gcrootmap._gcmap_deadentries += 1
-            expected = expected[1::2]
-            assert gcrootmap._gcmap_deadentries*6 > gcrootmap._gcmap_maxlength
-            # check that we can again insert 350 entries without a resize
-            oldgcmap = gcrootmap._gcmap
-            for i in range(0, 699, 2):
-                gcrootmap.put(515151 + i + repeat, 626262 + i)
-                expected.append((515151 + i + repeat, 626262 + i))
-            assert gcrootmap._gcmap == oldgcmap
-            check()
-
-    def test_freeing_block(self):
-        from pypy.jit.backend.llsupport import gc
-        class Asmgcroot:
-            arrayitemsize = 2 * llmemory.sizeof(llmemory.Address)
-            sort_count = 0
-            def sort_gcmap(self, gcmapstart, gcmapend):
-                self.sort_count += 1
-            def binary_search(self, gcmapstart, gcmapend, startaddr):
-                i = 0
-                while (i < gcrootmap._gcmap_curlength//2 and
-                       gcrootmap._gcmap[i*2] < startaddr):
-                    i += 1
-                if i > 0:
-                    i -= 1
-                assert 0 <= i < gcrootmap._gcmap_curlength//2
-                p = rffi.cast(rffi.CArrayPtr(llmemory.Address), gcmapstart)
-                p = rffi.ptradd(p, 2*i)
-                return llmemory.cast_ptr_to_adr(p)
-        saved = gc.asmgcroot
-        try:
-            gc.asmgcroot = Asmgcroot()
-            #
-            gcrootmap = GcRootMap_asmgcc()
-            gcrootmap._gcmap = lltype.malloc(gcrootmap.GCMAP_ARRAY,
-                                             1400, flavor='raw',
-                                             immortal=True)
-            for i in range(700):
-                gcrootmap._gcmap[i*2] = 1200000 + i
-                gcrootmap._gcmap[i*2+1] = i * 100 + 1
-            assert gcrootmap._gcmap_deadentries == 0
-            assert gc.asmgcroot.sort_count == 0
-            gcrootmap._gcmap_maxlength = 1400
-            gcrootmap._gcmap_curlength = 1400
-            gcrootmap._gcmap_sorted = False
-            #
-            gcrootmap.freeing_block(1200000 - 100, 1200000)
-            assert gcrootmap._gcmap_deadentries == 0
-            assert gc.asmgcroot.sort_count == 1
-            #
-            gcrootmap.freeing_block(1200000 + 100, 1200000 + 200)
-            assert gcrootmap._gcmap_deadentries == 100
-            assert gc.asmgcroot.sort_count == 1
-            for i in range(700):
-                if 100 <= i < 200:
-                    expected = 0
-                else:
-                    expected = i * 100 + 1
-                assert gcrootmap._gcmap[i*2] == 1200000 + i
-                assert gcrootmap._gcmap[i*2+1] == expected
-            #
-            gcrootmap.freeing_block(1200000 + 650, 1200000 + 750)
-            assert gcrootmap._gcmap_deadentries == 150
-            assert gc.asmgcroot.sort_count == 1
-            for i in range(700):
-                if 100 <= i < 200 or 650 <= i:
-                    expected = 0
-                else:
-                    expected = i * 100 + 1
-                assert gcrootmap._gcmap[i*2] == 1200000 + i
-                assert gcrootmap._gcmap[i*2+1] == expected
-        #
-        finally:
-            gc.asmgcroot = saved
-
-
-class TestGcRootMapShadowStack:
-    class FakeGcDescr:
-        force_index_ofs = 92
-
-    def test_make_shapes(self):
-        gcrootmap = GcRootMap_shadowstack(self.FakeGcDescr())
-        shape = gcrootmap.get_basic_shape()
-        gcrootmap.add_frame_offset(shape, 16)
-        gcrootmap.add_frame_offset(shape, -24)
-        assert shape == [16, -24]
-
-    def test_compress_callshape(self):
-        class FakeDataBlockWrapper:
-            def malloc_aligned(self, size, alignment):
-                assert alignment == 4    # even on 64-bits
-                assert size == 12        # 4*3, even on 64-bits
-                return rffi.cast(lltype.Signed, p)
-        datablockwrapper = FakeDataBlockWrapper()
-        p = lltype.malloc(rffi.CArray(rffi.INT), 3, immortal=True)
-        gcrootmap = GcRootMap_shadowstack(self.FakeGcDescr())
-        shape = [16, -24]
-        gcrootmap.compress_callshape(shape, datablockwrapper)
-        assert rffi.cast(lltype.Signed, p[0]) == 16
-        assert rffi.cast(lltype.Signed, p[1]) == -24
-        assert rffi.cast(lltype.Signed, p[2]) == 0
-
-
 class FakeLLOp(object):
     def __init__(self):
         self.record = []
@@ -324,10 +127,9 @@
                     return 43
 
         gcdescr = get_description(config_)
-        translator = FakeTranslator()
         llop1 = FakeLLOp()
-        gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), None,
-                                          llop1)
+        gc_ll_descr = gc.GcLLDescr_framework(gcdescr, FakeTranslator(), None,
+                                             llop1)
         gc_ll_descr.initialize()
         llop1.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
         self.llop1 = llop1
@@ -348,7 +150,7 @@
 
     def test_gc_malloc(self):
         S = lltype.GcStruct('S', ('x', lltype.Signed))
-        sizedescr = get_size_descr(self.gc_ll_descr, S)
+        sizedescr = descr.get_size_descr(self.gc_ll_descr, S)
         p = self.gc_ll_descr.gc_malloc(sizedescr)
         assert lltype.typeOf(p) == llmemory.GCREF
         assert self.llop1.record == [("fixedsize", repr(sizedescr.size),
@@ -356,7 +158,7 @@
 
     def test_gc_malloc_array(self):
         A = lltype.GcArray(lltype.Signed)
-        arraydescr = get_array_descr(self.gc_ll_descr, A)
+        arraydescr = descr.get_array_descr(self.gc_ll_descr, A)
         p = self.gc_ll_descr.gc_malloc_array(10, arraydescr)
         assert self.llop1.record == [("varsize", arraydescr.tid, 10,
                                       repr(arraydescr.basesize),
@@ -408,7 +210,7 @@
         gc_ll_descr = self.gc_ll_descr
         llop1 = self.llop1
         #
-        rewriter = GcRewriterAssembler(gc_ll_descr, None)
+        rewriter = gc.GcRewriterAssembler(gc_ll_descr, None)
         newops = rewriter.newops
         v_base = BoxPtr()
         v_value = BoxPtr()
@@ -462,3 +264,44 @@
 
 class TestFrameworkMiniMark(TestFramework):
     gc = 'minimark'
+
+def test_custom_tracer():
+    def indexof(no):
+        return (frame_adr + jitframe.getofs('jf_frame') +
+                jitframe.BASEITEMOFS + jitframe.SIGN_SIZE * no)
+    
+    PREV_STATICSIZE = jitframe.STATICSIZE
+    try:
+        jitframe.STATICSIZE = 3
+        frame_info = lltype.malloc(jitframe.JITFRAMEINFO)
+        frame = lltype.malloc(jitframe.JITFRAME, 15)
+        frame.jf_frame_info = frame_info
+        frame.jf_gcmap = lltype.malloc(jitframe.GCMAP, 4)
+        frame.jf_gcmap[0] = 5
+        frame.jf_gcmap[1] = 7
+        frame.jf_gcmap[2] = 8
+        frame.jf_gcmap[3] = 10
+        frame.jf_gcpattern = 1 | 4
+        frame_adr = llmemory.cast_ptr_to_adr(frame)
+        all_addrs = []
+        next = jitframe.jitframe_trace(frame_adr, llmemory.NULL)
+        while next:
+            all_addrs.append(next)
+            next = jitframe.jitframe_trace(frame_adr, next)
+        counter = 0
+        for name in jitframe.JITFRAME._names:
+            TP = getattr(jitframe.JITFRAME, name)
+            if isinstance(TP, lltype.Ptr): # only GC pointers
+                assert all_addrs[counter] == frame_adr + jitframe.getofs(name)
+                counter += 1
+        # gcpattern
+        assert all_addrs[6] == indexof(0)
+        assert all_addrs[7] == indexof(2)
+        assert all_addrs[8] == indexof(3 + 5)
+        assert all_addrs[9] == indexof(3 + 7)
+        assert all_addrs[10] == indexof(3 + 8)
+        assert all_addrs[11] == indexof(3 + 10)
+        assert len(all_addrs) == 6 + 4 + 2
+        # 6 static fields, 4 addresses from gcmap, 2 from gcpattern
+    finally:
+        jitframe.STATICSIZE = PREV_STATICSIZE
diff --git a/pypy/jit/backend/x86/assembler.py 
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -78,7 +78,6 @@
         self.propagate_exception_path = 0
         self.gcrootmap_retaddr_forced = 0
         self.teardown()
-        self.counter = 0
 
     def set_debug(self, v):
         r = self._debug
@@ -479,8 +478,6 @@
 
         clt = CompiledLoopToken(self.cpu, looptoken.number)
         clt.frame_info = lltype.malloc(jitframe.JITFRAMEINFO)
-        clt.frame_info.counter = self.counter
-        self.counter += 1
         clt.allgcrefs = []
         clt.frame_info.jfi_frame_depth = 0 # for now
         looptoken.compiled_loop_token = clt
diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py
--- a/pypy/jit/backend/x86/runner.py
+++ b/pypy/jit/backend/x86/runner.py
@@ -16,6 +16,8 @@
 from pypy.jit.backend.llsupport.symbolic import WORD
 from pypy.jit.backend.llsupport.descr import ArrayDescr, FLAG_POINTER,\
      FLAG_FLOAT
+
+jitframe.STATICSIZE = JITFRAME_FIXED_SIZE
         
 import sys
 
diff --git a/pypy/rpython/lltypesystem/llmemory.py 
b/pypy/rpython/lltypesystem/llmemory.py
--- a/pypy/rpython/lltypesystem/llmemory.py
+++ b/pypy/rpython/lltypesystem/llmemory.py
@@ -5,7 +5,7 @@
 # sizeof, offsetof
 
 import weakref
-from pypy.rlib.objectmodel import Symbolic
+from pypy.rlib.objectmodel import Symbolic, specialize
 from pypy.rpython.lltypesystem import lltype
 from pypy.tool.uid import uid
 from pypy.rlib.rarithmetic import is_valid_int
@@ -369,14 +369,15 @@
 
 # ____________________________________________________________
 
[email protected]()
 def _sizeof_none(TYPE):
     assert not TYPE._is_varsize()
     return ItemOffset(TYPE)
 _sizeof_none._annspecialcase_ = 'specialize:memo'
 
[email protected]()
 def _internal_array_field(TYPE):
     return TYPE._arrayfld, TYPE._flds[TYPE._arrayfld]
-_internal_array_field._annspecialcase_ = 'specialize:memo'
 
 def _sizeof_int(TYPE, n):
     if isinstance(TYPE, lltype.Struct):
@@ -385,6 +386,7 @@
     else:
         raise Exception("don't know how to take the size of a %r"%TYPE)
 
[email protected](0)
 def sizeof(TYPE, n=None):
     if n is None:
         return _sizeof_none(TYPE)
@@ -392,19 +394,23 @@
         return itemoffsetof(TYPE) + _sizeof_none(TYPE.OF) * n
     else:
         return _sizeof_int(TYPE, n)
-sizeof._annspecialcase_ = 'specialize:arg(0)'
 
[email protected]()
 def offsetof(TYPE, fldname):
     assert fldname in TYPE._flds
     return FieldOffset(TYPE, fldname)
-offsetof._annspecialcase_ = 'specialize:memo'
 
[email protected]()
 def itemoffsetof(TYPE, n=0):
     result = ArrayItemsOffset(TYPE)
     if n != 0:
         result += ItemOffset(TYPE.OF) * n
     return result
-itemoffsetof._annspecialcase_ = 'specialize:memo'
+
[email protected]()
+def arraylengthoffset(TYPE):
+    return ArrayLengthOffset(TYPE)
+
 # -------------------------------------------------------------
 
 class fakeaddress(object):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to