Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60422:019db8f1e708
Date: 2013-01-24 17:41 +0200
http://bitbucket.org/pypy/pypy/changeset/019db8f1e708/
Log: a fix and a failing test
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
@@ -151,6 +151,7 @@
self.newops.append(op0)
# XXX for now it generates call_malloc_gc, instead of
# call_malloc_nursery, because the array is strange
+
op1 = ResOperation(rop.NEW_ARRAY, [lgt_box], frame,
descr=descrs.arraydescr)
self.handle_new_array(descrs.arraydescr, op1)
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
@@ -866,6 +866,10 @@
self.mc.RET()
def _call_header_shadowstack(self, gcrootmap):
+ # we don't *really* have to do it, since we have the frame
+ # being referenced by the caller. However, we still do it
+ # to provide a place where we can read the frame from, in case
+ # we need to reload it after a collection
rst = gcrootmap.get_root_stack_top_addr()
if rx86.fits_in_32bits(rst):
self.mc.MOV_rj(eax.value, rst) # MOV eax, [rootstacktop]
diff --git a/rpython/jit/backend/x86/regalloc.py
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -891,6 +891,8 @@
size_box = op.getarg(0)
assert isinstance(size_box, ConstInt)
size = size_box.getint()
+ gcmap = self.get_gcmap() # allocate the gcmap *before*
+ # looking at the result
self.rm.force_allocate_reg(op.result, selected_reg=eax)
#
# We need edx as a temporary, but otherwise don't save any more
@@ -899,7 +901,6 @@
self.rm.force_allocate_reg(tmp_box, selected_reg=edi)
self.rm.possibly_free_var(tmp_box)
#
- gcmap = self.get_gcmap()
gc_ll_descr = self.assembler.cpu.gc_ll_descr
self.assembler.malloc_cond(
gc_ll_descr.get_nursery_free_addr(),
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
@@ -342,25 +342,54 @@
class GCClass:
JIT_WB_IF_FLAG = 0
- def __init__(self, nursery_size=100):
+ def __init__(self):
GcCache.__init__(self, False, None)
self._generated_functions = []
self.gcrootmap = MockShadowStackRootMap()
+ self.write_barrier_descr = WriteBarrierDescr(self)
+ self._initialize_for_tests()
+ self.frames = []
+
+ def malloc_slowpath(size):
+ self._collect()
+
+ self.malloc_slowpath_fnptr = llhelper_args(malloc_slowpath,
+ [lltype.Signed],
+ llmemory.GCREF)
+ self.all_nurseries = []
+
+ def init_nursery(self, nursery_size):
self.nursery = lltype.malloc(rffi.CArray(lltype.Char), nursery_size,
- flavor='raw')
+ flavor='raw', zero=True)
self.nursery_ptrs = lltype.malloc(rffi.CArray(lltype.Signed), 2,
flavor='raw')
self.nursery_ptrs[0] = rffi.cast(lltype.Signed, self.nursery)
self.nursery_ptrs[1] = self.nursery_ptrs[0] + nursery_size
self.nursery_addr = rffi.cast(lltype.Signed, self.nursery_ptrs)
- self.write_barrier_descr = WriteBarrierDescr(self)
- self._initialize_for_tests()
+ self.all_nurseries.append(self.nursery)
+ self.collections.reverse()
+
+ def _collect(self):
+ gcmap = unpack_gcmap(self.frames[-1])
+ col = self.collections.pop()
+ frame = self.frames[-1].jf_frame
+ start = self.nursery_ptrs[0]
+ assert len(gcmap) == len(col)
+ for i in range(len(gcmap)):
+ assert col[i] + start == frame[gcmap[i]]
+
+ def malloc_jitframe(self, frame_info):
+ """ Allocate a new frame, overwritten by tests
+ """
+ frame = jitframe.JITFRAME.allocate(frame_info)
+ self.frames.append(frame)
+ return frame
def do_write_barrier(self, gcref_struct, gcref_newptr):
pass
def get_malloc_slowpath_addr(self):
- return 0
+ return self.malloc_slowpath_fnptr
def get_nursery_free_addr(self):
return self.nursery_addr
@@ -369,7 +398,8 @@
return self.nursery_addr + rffi.sizeof(lltype.Signed)
def __del__(self):
- lltype.free(self.nursery, flavor='raw')
+ for nursery in self.all_nurseries:
+ lltype.free(nursery, flavor='raw')
lltype.free(self.nursery_ptrs, flavor='raw')
def unpack_gcmap(frame):
@@ -391,7 +421,6 @@
cpu.gc_ll_descr = GCDescrShadowstackDirect()
wbd = cpu.gc_ll_descr.write_barrier_descr
wbd.jit_wb_if_flag_byteofs = 0 # directly into 'hdr' field
- cpu.setup_once()
S = lltype.GcForwardReference()
S.become(lltype.GcStruct('S',
('hdr', lltype.Signed),
@@ -402,6 +431,8 @@
def test_shadowstack_call(self):
cpu = self.cpu
+ cpu.gc_ll_descr.init_nursery(100)
+ cpu.setup_once()
S = self.S
ofs = cpu.get_baseofs_of_frame_field()
frames = []
@@ -466,13 +497,21 @@
cpu = self.cpu
sizeof = cpu.sizeof(self.S)
sizeof.tid = 0
+ size = sizeof.size
loop = self.parse("""
[]
- p0 = new(descr=sizedescr)
+ p0 = call_malloc_nursery(%d)
+ p1 = call_malloc_nursery(%d)
+ p2 = call_malloc_nursery(%d) # this overflows
+ guard_nonnull(p2, descr=faildescr) [p0, p1, p2]
finish(p0, descr=finaldescr)
- """, namespace={'sizedescr': sizeof,
- 'finaldescr': BasicFinalDescr()})
+ """ % (size, size, size), namespace={'sizedescr': sizeof,
+ 'finaldescr': BasicFinalDescr(),
+ 'faildescr': BasicFailDescr()})
token = JitCellToken()
+ cpu.gc_ll_descr.collections = [[0, sizeof.size]]
+ cpu.gc_ll_descr.init_nursery(2 * sizeof.size)
+ cpu.setup_once()
cpu.compile_loop(loop.inputargs, loop.operations, token)
frame = cpu.execute_token(token)
# now we should be able to track everything from the frame
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit