Author: Maciej Fijalkowski <fij...@gmail.com> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit