Author: Maciej Fijalkowski <fij...@gmail.com> Branch: jitframe-on-heap Changeset: r60415:2b69388c82c3 Date: 2013-01-24 12:00 +0200 http://bitbucket.org/pypy/pypy/changeset/2b69388c82c3/
Log: a bit undertested write barrier for frames 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 @@ -1258,6 +1258,13 @@ mc.MOV(ebp, mem(edx, -WORD)) base_ofs = self.cpu.get_baseofs_of_frame_field() mc.ADD_ri(ebp.value, base_ofs) + wbdescr = self.cpu.gc_ll_descr.write_barrier_descr + if gcrootmap and wbdescr: + ofs = self.cpu.get_baseofs_of_frame_field() + # frame never uses card marking, so we enforce this is not + # an array + self._write_barrier_fastpah(wbdescr, [ebp], array=False, + extra_ofs=-ofs) def call(self, addr, args, res): self._emit_call(imm(addr), args) @@ -2311,20 +2318,18 @@ self.mc.overwrite(jmp_location - 1, chr(offset)) self._emit_guard_not_forced(guard_token) - def genop_discard_cond_call_gc_wb(self, op, arglocs): + def _write_barrier_fastpah(self, descr, arglocs, array=False, extra_ofs=0): # Write code equivalent to write_barrier() in the GC: it checks # a flag in the object at arglocs[0], and if set, it calls a # helper piece of assembler. The latter saves registers as needed # and call the function jit_remember_young_pointer() from the GC. - descr = op.getdescr() if we_are_translated(): cls = self.cpu.gc_ll_descr.has_write_barrier_class() assert cls is not None and isinstance(descr, cls) # - opnum = op.getopnum() card_marking = False mask = descr.jit_wb_if_flag_singlebyte - if opnum == rop.COND_CALL_GC_WB_ARRAY and descr.jit_wb_cards_set != 0: + if array and descr.jit_wb_cards_set != 0: # assumptions the rest of the function depends on: assert (descr.jit_wb_cards_set_byteofs == descr.jit_wb_if_flag_byteofs) @@ -2333,7 +2338,8 @@ mask = descr.jit_wb_if_flag_singlebyte | -0x80 # loc_base = arglocs[0] - self.mc.TEST8(addr_add_const(loc_base, descr.jit_wb_if_flag_byteofs), + self.mc.TEST8(addr_add_const(loc_base, + descr.jit_wb_if_flag_byteofs + extra_ofs), imm(mask)) self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later jz_location = self.mc.get_relative_pos() @@ -2418,7 +2424,11 @@ assert 0 < offset <= 127 self.mc.overwrite(jz_location-1, chr(offset)) - genop_discard_cond_call_gc_wb_array = genop_discard_cond_call_gc_wb + def genop_discard_cond_call_gc_wb(self, op, arglocs): + self._write_barrier_fastpah(op.getdescr(), arglocs) + + def genop_discard_cond_call_gc_wb_array(self, op, arglocs): + self._write_barrier_fastpah(op.getdescr(), arglocs, array=True) def not_implemented_op_discard(self, op, arglocs): not_implemented("not implemented operation: %s" % op.getopname()) diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py b/rpython/jit/backend/x86/test/test_gc_integration.py --- a/rpython/jit/backend/x86/test/test_gc_integration.py +++ b/rpython/jit/backend/x86/test/test_gc_integration.py @@ -236,7 +236,7 @@ assert len(x) == 1 assert (bin(x[0]).count('1') == '0b1111100000000000000001111111011111'.count('1')) - # all but two + # all but two registers + some stuff on stack self.cpu = self.getcpu(check) S1 = lltype.GcStruct('S1') @@ -328,16 +328,22 @@ class GCClass: JIT_WB_IF_FLAG = 0 + def __init__(self, nursery_size=100): + GcCache.__init__(self, False, None) + self.gcrootmap = MockShadowStackRootMap() + self.nursery = lltype.malloc(rffi.CArray(lltype.Char), nursery_size, + flavor='raw') + self.nursery_addr = rffi.cast(lltype.Signed, self.nursery) + def get_malloc_slowpath_addr(self): return 0 def get_nursery_free_addr(self): return 0 + + def __del__(self): + lltype.free(self.nursery, flavor='raw') - def __init__(self): - GcCache.__init__(self, False, None) - self.gcrootmap = MockShadowStackRootMap() - def unpack_gcmap(frame): res = [] val = 0 @@ -351,17 +357,20 @@ return res class TestGcShadowstackDirect(BaseTestRegalloc): - - cpu = CPU(None, None) - cpu.gc_ll_descr = GCDescrShadowstackDirect() - cpu.setup_once() + + def setup_method(self, meth): + cpu = CPU(None, None) + cpu.gc_ll_descr = GCDescrShadowstackDirect() + cpu.setup_once() + self.cpu = cpu def test_shadowstack_call(self): - ofs = self.cpu.get_baseofs_of_frame_field() + cpu = self.cpu + ofs = cpu.get_baseofs_of_frame_field() frames = [] def check(i): - assert self.cpu.gc_ll_descr.gcrootmap.stack[0] == i - ofs + assert cpu.gc_ll_descr.gcrootmap.stack[0] == i - ofs frame = rffi.cast(jitframe.JITFRAMEPTR, i - ofs) assert len(frame.jf_frame) == JITFRAME_FIXED_SIZE + 4 # we "collect" @@ -371,13 +380,13 @@ assert gcmap == [28, 29, 30] for item, s in zip(gcmap, new_items): new_frame.jf_frame[item] = rffi.cast(lltype.Signed, s) - assert self.cpu.gc_ll_descr.gcrootmap.stack[0] == rffi.cast(lltype.Signed, frame) + assert cpu.gc_ll_descr.gcrootmap.stack[0] == rffi.cast(lltype.Signed, frame) hdrbuilder.new_header(new_frame) gc_ll_descr.gcrootmap.stack[0] = rffi.cast(lltype.Signed, new_frame) frames.append(new_frame) def check2(i): - assert self.cpu.gc_ll_descr.gcrootmap.stack[0] == i - ofs + assert cpu.gc_ll_descr.gcrootmap.stack[0] == i - ofs frame = rffi.cast(jitframe.JITFRAMEPTR, i - ofs) assert frame == frames[1] assert frame != frames[0] @@ -385,7 +394,7 @@ CHECK = lltype.FuncType([lltype.Signed], lltype.Void) checkptr = llhelper(lltype.Ptr(CHECK), check) check2ptr = llhelper(lltype.Ptr(CHECK), check2) - checkdescr = self.cpu.calldescrof(CHECK, CHECK.ARGS, CHECK.RESULT, + checkdescr = cpu.calldescrof(CHECK, CHECK.ARGS, CHECK.RESULT, EffectInfo.MOST_GENERAL) S = lltype.GcForwardReference() @@ -404,13 +413,13 @@ 'faildescr': BasicFailDescr(), 'check_adr': checkptr, 'check2_adr': check2ptr, 'checkdescr': checkdescr, - 'fielddescr': self.cpu.fielddescrof(S, 'x')}) + 'fielddescr': cpu.fielddescrof(S, 'x')}) token = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, token) - self.cpu.register_frame = lambda frame : hdrbuilder.new_header(frame) + cpu.compile_loop(loop.inputargs, loop.operations, token) + cpu.register_frame = lambda frame : hdrbuilder.new_header(frame) HDR = lltype.Struct('HDR', ('tid', lltype.Signed)) hdrbuilder = GCHeaderBuilder(HDR) - gc_ll_descr = self.cpu.gc_ll_descr + gc_ll_descr = cpu.gc_ll_descr gc_ll_descr.gcheaderbuilder = hdrbuilder gc_ll_descr.HDRPTR = lltype.Ptr(HDR) p0 = lltype.malloc(S, zero=True) @@ -421,10 +430,13 @@ hdrbuilder.new_header(p0) hdrbuilder.new_header(p1) hdrbuilder.new_header(p2) - frame = self.cpu.execute_token(token, p0, p1, p2) + frame = cpu.execute_token(token, p0, p1, p2) frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) gcmap = unpack_gcmap(lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame)) assert len(gcmap) == 1 assert gcmap[0] < 29 item = rffi.cast(lltype.Ptr(S), frame.jf_frame[gcmap[0]]) assert item == new_items[2] + + def test_malloc_slowpath(self): + cpu = self.cpu _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit