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