Author: Remi Meier <[email protected]>
Branch: stmgc-c4
Changeset: r66116:49e406509329
Date: 2013-08-13 15:31 +0200
http://bitbucket.org/pypy/pypy/changeset/49e406509329/
Log: fix forgotten jitframe allocation before call_assembler
diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py
--- a/pypy/tool/jitlogparser/parser.py
+++ b/pypy/tool/jitlogparser/parser.py
@@ -100,7 +100,7 @@
if ofs >= 0:
asm.append((ofs, v.strip("\n")))
#
- prefix = hex(dump_start)[:-8]
+ prefix = hex(dump_start)[:-9]
asm_index = 0
for i, op in enumerate(loop.operations):
end = 0
diff --git a/rpython/jit/backend/llsupport/assembler.py
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -226,7 +226,6 @@
else:
raise AssertionError(kind)
- import pdb;pdb.set_trace()
gcref = cast_instance_to_gcref(value)
gcref = rgc._make_sure_does_not_move(gcref)
value = rffi.cast(lltype.Signed, gcref)
diff --git a/rpython/jit/backend/llsupport/rewrite.py
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -172,8 +172,8 @@
size_box,
descr=descrs.jfi_frame_size)
self.newops.append(op0)
- self.gen_malloc_nursery_varsize_frame(size_box, frame)
- self.gen_initialize_tid(frame, descrs.arraydescr.tid)
+ self.gen_malloc_nursery_varsize_frame(size_box, frame,
+ descrs.arraydescr.tid)
length_box = history.BoxInt()
op1 = ResOperation(rop.GETFIELD_GC, [history.ConstInt(frame_info)],
length_box,
@@ -321,7 +321,7 @@
self.recent_mallocs[v_result] = None
return True
- def gen_malloc_nursery_varsize_frame(self, sizebox, v_result):
+ def gen_malloc_nursery_varsize_frame(self, sizebox, v_result, tid):
""" Generate CALL_MALLOC_NURSERY_VARSIZE_FRAME
"""
self.emitting_an_operation_that_can_collect()
@@ -332,6 +332,8 @@
self.newops.append(op)
self.recent_mallocs[v_result] = None
+ self.gen_initialize_tid(v_result, tid)
+
def gen_malloc_nursery(self, size, v_result):
"""Try to generate or update a CALL_MALLOC_NURSERY.
If that fails, generate a plain CALL_MALLOC_GC instead.
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -3,6 +3,7 @@
from rpython.jit.metainterp.history import BoxPtr, ConstPtr, ConstInt
from rpython.rlib.objectmodel import specialize
from rpython.rlib.objectmodel import we_are_translated
+from rpython.jit.metainterp import history
#
# STM Support
@@ -92,11 +93,13 @@
continue
# ---------- calls ----------
if op.is_call():
- self.known_category.clear()
if op.getopnum() == rop.CALL_RELEASE_GIL:
self.fallback_inevitable(op)
+ elif op.getopnum() == rop.CALL_ASSEMBLER:
+ self.handle_call_assembler(op)
else:
self.newops.append(op)
+ self.known_category.clear()
continue
# ---------- copystrcontent ----------
if op.getopnum() in (rop.COPYSTRCONTENT,
@@ -138,8 +141,15 @@
for v, c in self.known_category.items():
if c == 'R':
self.known_category[v] = 'P'
-
-
+
+ def gen_malloc_nursery_varsize_frame(self, sizebox, v_result, tid):
+ """ Generate CALL_MALLOC_NURSERY_VARSIZE_FRAME
+ """
+ addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_big_fixedsize')
+ args = [ConstInt(addr), sizebox, ConstInt(tid)]
+ descr = self.gc_ll_descr.malloc_big_fixedsize_descr
+ self._gen_call_malloc_gc(args, v_result, descr)
+
def gen_write_barrier(self, v):
raise NotImplementedError
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -876,6 +876,19 @@
return rst
def _call_header_shadowstack(self, gcrootmap):
+ # do a write-barrier on ebp / frame for stm
+ # XXX: may not be necessary if we are sure that we only get
+ # freshly allocated frames or already write-ready frames
+ # from the caller...
+ gc_ll_descr = self.cpu.gc_ll_descr
+ gcrootmap = gc_ll_descr.gcrootmap
+ if gcrootmap and gcrootmap.is_stm:
+ if not hasattr(gc_ll_descr, 'P2Wdescr'):
+ raise Exception("unreachable code")
+ wbdescr = gc_ll_descr.P2Wdescr
+ self._stm_barrier_fastpath(self.mc, wbdescr, [ebp], is_frame=True)
+
+ # put the frame in ebp on the shadowstack for the GC to find
rst = self._load_shadowstack_top_in_ebx(self.mc, gcrootmap)
self.mc.MOV_mr((ebx.value, 0), ebp.value) # MOV [ebx], ebp
self.mc.ADD_ri(ebx.value, WORD)
diff --git a/rpython/jit/backend/x86/test/test_stm_integration.py
b/rpython/jit/backend/x86/test/test_stm_integration.py
--- a/rpython/jit/backend/x86/test/test_stm_integration.py
+++ b/rpython/jit/backend/x86/test/test_stm_integration.py
@@ -20,6 +20,7 @@
from rpython.jit.backend.llsupport import jitframe
from rpython.memory.gc.stmgc import StmGC
from rpython.jit.metainterp import history
+from rpython.jit.codewriter.effectinfo import EffectInfo
import itertools, sys
import ctypes
@@ -101,6 +102,11 @@
class FakeGCHeaderBuilder:
size_gc_header = WORD
+GCPTR = lltype.Ptr(lltype.GcStruct(
+ 'GCPTR', ('h_tid', lltype.Unsigned),
+ ('h_revision', lltype.Signed),
+ ('h_original', lltype.Unsigned)))
+HDRSIZE = 3 * WORD
class GCDescrStm(GCDescrShadowstackDirect):
def __init__(self):
@@ -147,6 +153,21 @@
self.generate_function('stm_ptr_eq', ptr_eq, [llmemory.GCREF] * 2,
RESULT=lltype.Bool)
+ def malloc_big_fixedsize(size, tid):
+ entries = size + HDRSIZE
+ TP = rffi.CArray(lltype.Char)
+ obj = lltype.malloc(TP, n=entries, flavor='raw',
+ track_allocation=False, zero=True)
+ objptr = rffi.cast(GCPTR, obj)
+ objptr.h_tid = rffi.cast(lltype.Unsigned,
+ StmGC.GCFLAG_OLD|StmGC.GCFLAG_WRITE_BARRIER
+ | tid)
+ objptr.h_revision = rffi.cast(lltype.Signed, -sys.maxint)
+ return rffi.cast(llmemory.GCREF, objptr)
+ self.generate_function('malloc_big_fixedsize', malloc_big_fixedsize,
+ [lltype.Signed] * 2)
+
+
def malloc_jitframe(self, frame_info):
""" Allocate a new frame, overwritten by tests
"""
@@ -180,6 +201,7 @@
def setup_method(self, meth):
cpu = CPU(None, None)
cpu.gc_ll_descr = GCDescrStm()
+
self.p2wd = cpu.gc_ll_descr.P2Wdescr
self.p2rd = cpu.gc_ll_descr.P2Rdescr
@@ -205,7 +227,7 @@
def assert_in(self, called_on, args):
for i, ref in enumerate(args):
- assert rffi.cast_ptr_to_adr(ref) == called_on[i]
+ assert rffi.cast_ptr_to_adr(ref) in called_on
def assert_not_in(self, called_on, args):
for ref in args:
@@ -267,7 +289,7 @@
# check if rev-fastpath worked
if rev == PRIV_REV:
# fastpath
- assert not called_on
+ self.assert_not_in(called_on, [sgcref])
else:
self.assert_in(called_on, [sgcref])
@@ -310,7 +332,7 @@
# check if rev-fastpath worked
if rev == PRIV_REV:
# fastpath and WRITE_BARRIER not set
- assert not called_on
+ self.assert_not_in(called_on, [sgcref])
else:
self.assert_in(called_on, [sgcref])
@@ -412,6 +434,70 @@
assert guard_failed
+
+
+ def test_assembler_call(self):
+ cpu = self.cpu
+ cpu.gc_ll_descr.init_nursery(100)
+ cpu.setup_once()
+
+ called = []
+ def assembler_helper(deadframe, virtualizable):
+ frame = rffi.cast(JITFRAMEPTR, deadframe)
+ frame_adr = rffi.cast(lltype.Signed, frame.jf_descr)
+ called.append(frame_adr)
+ return 4 + 9
+
+ FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF,
+ llmemory.GCREF],
+ lltype.Signed))
+ class FakeJitDriverSD:
+ index_of_virtualizable = -1
+ _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper)
+ assembler_helper_adr = llmemory.cast_ptr_to_adr(
+ _assembler_helper_ptr)
+
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+ i10 = int_add(i0, i1)
+ i11 = int_add(i10, i2)
+ i12 = int_add(i11, i3)
+ i13 = int_add(i12, i4)
+ i14 = int_add(i13, i5)
+ i15 = int_add(i14, i6)
+ i16 = int_add(i15, i7)
+ i17 = int_add(i16, i8)
+ i18 = int_add(i17, i9)
+ finish(i18)'''
+ loop = parse(ops)
+ looptoken = JitCellToken()
+ looptoken.outermost_jitdriver_sd = FakeJitDriverSD()
+ finish_descr = loop.operations[-1].getdescr()
+ self.cpu.done_with_this_frame_descr_int = BasicFinalDescr()
+ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+ ARGS = [lltype.Signed] * 10
+ RES = lltype.Signed
+ FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
+ lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
+ EffectInfo.MOST_GENERAL)
+ args = [i+1 for i in range(10)]
+ deadframe = self.cpu.execute_token(looptoken, *args)
+
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+ i10 = int_add(i0, 42)
+ i11 = call_assembler(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9,
descr=looptoken)
+ guard_not_forced()[]
+ finish(i11)
+ '''
+ loop = parse(ops, namespace=locals())
+ othertoken = JitCellToken()
+ self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
+ args = [i+1 for i in range(10)]
+ deadframe = self.cpu.execute_token(othertoken, *args)
+ assert called == [id(finish_descr)]
+
+
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit