Author: Remi Meier <remi.me...@gmail.com> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit