Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60541:cf0aed3ee46e
Date: 2013-01-27 22:21 +0200
http://bitbucket.org/pypy/pypy/changeset/cf0aed3ee46e/
Log: implement rewriting of frame malloc
diff --git a/rpython/jit/backend/llsupport/gc.py
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -122,6 +122,8 @@
for name in ['jf_descr', 'jf_guard_exc', 'jf_force_descr',
'jf_frame_info', 'jf_gcmap']:
setattr(descrs, name, cpu.fielddescrof(jitframe.JITFRAME, name))
+ descrs.jfi_frame_size = cpu.fielddescrof(jitframe.JITFRAMEINFO,
+ 'jfi_frame_size')
descrs.jfi_frame_depth = cpu.fielddescrof(jitframe.JITFRAMEINFO,
'jfi_frame_depth')
return descrs
diff --git a/rpython/jit/backend/llsupport/jitframe.py
b/rpython/jit/backend/llsupport/jitframe.py
--- a/rpython/jit/backend/llsupport/jitframe.py
+++ b/rpython/jit/backend/llsupport/jitframe.py
@@ -14,10 +14,19 @@
GCMAP = lltype.GcArray(lltype.Unsigned)
NULLGCMAP = lltype.nullptr(GCMAP)
+def jitframeinfo_set_depth(jfi, new_depth):
+ jfi.jfi_frame_depth = new_depth
+ jfi.jfi_frame_size = STATICSIZE + new_depth * SIZEOFSIGNED
+
JITFRAMEINFO = lltype.GcStruct(
'JITFRAMEINFO',
- # the depth of frame
+ # the depth of the frame
('jfi_frame_depth', lltype.Signed),
+ # the total size of the frame, in bytes
+ ('jfi_frame_size', lltype.Signed),
+ adtmeths = {
+ 'set_frame_depth': jitframeinfo_set_depth,
+ },
)
NULLFRAMEINFO = lltype.nullptr(JITFRAMEINFO)
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
@@ -137,22 +137,42 @@
else:
raise NotImplementedError(op.getopname())
+ def gen_malloc_frame(self, frame_info, frame, size_box):
+ descrs = self.gc_ll_descr.getframedescrs(self.cpu)
+ if self.gc_ll_descr.kind == 'boehm':
+ op0 = ResOperation(rop.GETFIELD_GC, [history.ConstPtr(frame_info)],
+ size_box,
+ descr=descrs.jfi_frame_depth)
+ self.newops.append(op0)
+ op1 = ResOperation(rop.NEW_ARRAY, [size_box], frame,
+ descr=descrs.arraydescr)
+ self.handle_new_array(descrs.arraydescr, op1)
+ else:
+ # we read size in bytes here, not the length
+ op0 = ResOperation(rop.GETFIELD_GC, [history.ConstPtr(frame_info)],
+ size_box,
+ descr=descrs.jfi_frame_size)
+ self.newops.append(op0)
+ self.gen_malloc_nursery_varsize(size_box, frame, is_small=True)
+ self.gen_initialize_tid(frame, descrs.arraydescr.tid)
+ length_box = history.BoxInt()
+ op1 = ResOperation(rop.GETFIELD_GC, [history.ConstPtr(frame_info)],
+ length_box,
+ descr=descrs.jfi_frame_depth)
+ self.newops.append(op1)
+ self.gen_initialize_len(frame, length_box,
+ descrs.arraydescr.lendescr)
+
def handle_call_assembler(self, op):
descrs = self.gc_ll_descr.getframedescrs(self.cpu)
loop_token = op.getdescr()
assert isinstance(loop_token, history.JitCellToken)
- lgt_box = history.BoxInt()
- frame = history.BoxPtr()
jfi = loop_token.compiled_loop_token.frame_info
llref = lltype.cast_opaque_ptr(llmemory.GCREF, jfi)
rgc._make_sure_does_not_move(llref)
- op0 = ResOperation(rop.GETFIELD_GC, [history.ConstPtr(llref)], lgt_box,
- descr=descrs.jfi_frame_depth)
- self.newops.append(op0)
-
- op1 = ResOperation(rop.NEW_ARRAY, [lgt_box], frame,
- descr=descrs.arraydescr)
- self.handle_new_array(descrs.arraydescr, op1)
+ size_box = history.BoxInt()
+ frame = history.BoxPtr()
+ self.gen_malloc_frame(llref, frame, size_box)
op2 = ResOperation(rop.SETFIELD_GC, [frame, history.ConstPtr(llref)],
None, descr=descrs.jf_frame_info)
self.newops.append(op2)
@@ -258,6 +278,18 @@
self._gen_call_malloc_gc([ConstInt(addr), v_num_elem], v_result,
self.gc_ll_descr.malloc_unicode_descr)
+ def gen_malloc_nursery_varsize(self, sizebox, v_result, is_small=False):
+ """ Generate CALL_MALLOC_NURSERY_VARSIZE_SMALL
+ """
+ assert is_small
+ self.emitting_an_operation_that_can_collect()
+ op = ResOperation(rop.CALL_MALLOC_NURSERY_VARSIZE_SMALL,
+ [sizebox],
+ v_result)
+
+ self.newops.append(op)
+ self.recent_mallocs[v_result] = None
+
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/test/test_rewrite.py
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -76,8 +76,11 @@
ll_frame_info = lltype.cast_opaque_ptr(llmemory.GCREF, frame_info)
clt.frame_info = frame_info
frame_info.jfi_frame_depth = 13
+ frame_info.jfi_frame_size = 255
framedescrs = self.gc_ll_descr.getframedescrs(self.cpu)
+ framelendescr = framedescrs.arraydescr.lendescr
jfi_frame_depth = framedescrs.jfi_frame_depth
+ jfi_frame_size = framedescrs.jfi_frame_size
jf_frame_info = framedescrs.jf_frame_info
signedframedescr = self.cpu.signedframedescr
floatframedescr = self.cpu.floatframedescr
@@ -737,12 +740,13 @@
i2 = call_assembler(i0, f0, descr=casmdescr)
""", """
[i0, f0]
- i1 = getfield_gc(ConstPtr(ll_frame_info), descr=jfi_frame_depth)
- p1 = call_malloc_nursery(13)
+ i1 = getfield_gc(ConstPtr(ll_frame_info), descr=jfi_frame_size)
+ p1 = call_malloc_nursery_varsize_small(i1)
+ setfield_gc(p1, 0, descr=tiddescr)
+ i2 = getfield_gc(ConstPtr(ll_frame_info), descr=jfi_frame_depth)
+ setfield_gc(p1, i2, descr=framelendescr)
setfield_gc(p1, ConstPtr(ll_frame_info), descr=jf_frame_info)
setarrayitem_gc(p1, 0, i0, descr=signedframedescr)
setarrayitem_gc(p1, 1, f0, descr=floatframedescr)
- i2 = call_assembler(p1, descr=casmdescr)
+ i3 = call_assembler(p1, descr=casmdescr)
""")
- # XXX we want call_malloc_nursery actually, but let's not care
- # for now, the array is a bit non-standard
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
@@ -507,7 +507,7 @@
clt = CompiledLoopToken(self.cpu, looptoken.number)
clt.frame_info = lltype.malloc(jitframe.JITFRAMEINFO)
clt.allgcrefs = []
- clt.frame_info.jfi_frame_depth = 0 # for now
+ clt.frame_info.set_frame_depth(0) # for now
looptoken.compiled_loop_token = clt
clt._debug_nbargs = len(inputargs)
if not we_are_translated():
@@ -666,13 +666,13 @@
mc.copy_to_raw_memory(rawstart + pos_after_jz - 4)
def update_frame_depth(self, frame_depth):
- self.current_clt.frame_info.jfi_frame_depth = frame_depth
+ self.current_clt.frame_info.set_frame_depth(frame_depth)
new_jumping_to = []
for wref in self.current_clt.jumping_to:
clt = wref()
if clt is not None:
- clt.frame_info.jfi_frame_depth = max(frame_depth,
- clt.frame_info.jfi_frame_depth)
+ clt.frame_info.set_frame_depth(max(frame_depth,
+ clt.frame_info.jfi_frame_depth))
new_jumping_to.append(weakref.ref(clt))
self.current_clt.jumping_to = new_jumping_to
@@ -898,7 +898,7 @@
# copy frame-info data
old_fi = oldlooptoken.compiled_loop_token.frame_info
new_fi = newlooptoken.compiled_loop_token.frame_info
- old_fi.jfi_frame_depth = new_fi.jfi_frame_depth
+ old_fi.set_frame_depth(new_fi.jfi_frame_depth)
mc = codebuf.MachineCodeBlockWrapper()
mc.JMP(imm(target))
if WORD == 4: # keep in sync with prepare_loop()
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
@@ -451,6 +451,8 @@
setattr(descrs, name, cpu.fielddescrof(JITFRAME, name))
descrs.jfi_frame_depth = cpu.fielddescrof(jitframe.JITFRAMEINFO,
'jfi_frame_depth')
+ descrs.jfi_frame_size = cpu.fielddescrof(jitframe.JITFRAMEINFO,
+ 'jfi_frame_size')
return descrs
def do_write_barrier(self, gcref_struct, gcref_newptr):
diff --git a/rpython/jit/backend/x86/test/test_zrpy_gc.py
b/rpython/jit/backend/x86/test/test_zrpy_gc.py
--- a/rpython/jit/backend/x86/test/test_zrpy_gc.py
+++ b/rpython/jit/backend/x86/test/test_zrpy_gc.py
@@ -790,5 +790,11 @@
def test_compile_framework_minimal_size_in_nursery(self):
self.run('compile_framework_minimal_size_in_nursery')
+ #def define_compile_framework_call_assembler(self):
+ # xxx
+
+ #def test_compile_framework_call_assembler(self):
+ # self.run('compile_framework_call_assembler')
+
class TestShadowStack(CompileFrameworkTests):
gcrootfinder = "shadowstack"
diff --git a/rpython/jit/metainterp/executor.py
b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -354,6 +354,7 @@
rop.QUASIIMMUT_FIELD,
rop.CALL_MALLOC_GC,
rop.CALL_MALLOC_NURSERY,
+ rop.CALL_MALLOC_NURSERY_VARSIZE_SMALL,
rop.LABEL,
): # list of opcodes never executed by pyjitpl
continue
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit