Author: Maciej Fijalkowski <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit