[pypy-commit] pypy jitframe-on-heap: basic integration, reloading of frame
fijal
noreply at buildbot.pypy.org
Mon Jan 21 11:39:27 CET 2013
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: jitframe-on-heap
Changeset: r60291:c3e92471a8d8
Date: 2013-01-21 12:36 +0200
http://bitbucket.org/pypy/pypy/changeset/c3e92471a8d8/
Log: basic integration, reloading of frame
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
@@ -1228,6 +1228,13 @@
self.mc.CALL(x)
if align:
self.mc.ADD_ri(esp.value, align * WORD)
+ gcrootmap = self.cpu.gc_ll_descr.gcrootmap
+ if gcrootmap and gcrootmap.is_shadow_stack:
+ rst = gcrootmap.get_root_stack_top_addr()
+ self.mc.MOV(edx, heap(rst))
+ self.mc.MOV(ebp, mem(edx, -WORD))
+ base_ofs = self.cpu.get_baseofs_of_frame_field()
+ self.mc.ADD_ri(ebp.value, base_ofs)
def call(self, addr, args, res):
self._emit_call(imm(addr), args)
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
@@ -2,16 +2,19 @@
""" Tests for register allocation for common constructs
"""
-from rpython.jit.metainterp.history import TargetToken, BasicFinalDescr
+from rpython.jit.metainterp.history import TargetToken, BasicFinalDescr,\
+ JitCellToken
from rpython.jit.backend.llsupport.gc import GcLLDescription, GcLLDescr_boehm,\
- GcLLDescr_framework
+ GcLLDescr_framework, GcCache
from rpython.jit.backend.detect_cpu import getcpuclass
-from rpython.jit.backend.x86.arch import WORD
+from rpython.jit.backend.x86.arch import WORD, JITFRAME_FIXED_SIZE
from rpython.jit.backend.llsupport import jitframe
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.rtyper.annlowlevel import llhelper
from rpython.jit.backend.x86.test.test_regalloc import BaseTestRegalloc
from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls
+from rpython.jit.codewriter.effectinfo import EffectInfo
CPU = getcpuclass()
@@ -321,14 +324,81 @@
s1 = lltype.cast_opaque_ptr(lltype.Ptr(S1), s1ref)
assert s1 == getattr(s2, 's%d' % i)
-class TestGcShadowstackDirect(object):
+class MockShadowStackRootMap(object):
+ is_shadow_stack = True
+
+ def __init__(self):
+ TP = rffi.CArray(lltype.Signed)
+ self.stack = lltype.malloc(TP, 10, flavor='raw')
+ self.stack_addr = lltype.malloc(TP, 1,
+ flavor='raw')
+ self.stack_addr[0] = rffi.cast(lltype.Signed, self.stack)
+
+ def __del__(self):
+ lltype.free(self.stack_addr, flavor='raw')
+ lltype.free(self.stack, flavor='raw')
+
+ def register_asm_addr(self, start, mark):
+ pass
+
+ def get_root_stack_top_addr(self):
+ return rffi.cast(lltype.Signed, self.stack_addr)
+
+class GCDescrShadowstackDirect(GcLLDescr_framework):
+ layoutbuilder = None
+ write_barrier_descr = None
+
+ def get_malloc_slowpath_addr(self):
+ return 0
+
+ def get_nursery_free_addr(self):
+ return 0
+
+ def __init__(self):
+ GcCache.__init__(self, False, None)
+ self.gcrootmap = MockShadowStackRootMap()
+
+class TestGcShadowstackDirect(BaseTestRegalloc):
cpu = CPU(None, None)
- cpu.gc_ll_descr = GcLLDescr_framework(None, None, None)
+ cpu.gc_ll_descr = GCDescrShadowstackDirect()
cpu.setup_once()
def test_shadowstack_call(self):
- ops = parse("""
+ ofs = self.cpu.get_baseofs_of_frame_field()
+ frames = []
+
+ def check(i):
+ assert self.cpu.gc_ll_descr.gcrootmap.stack[0] == i - ofs
+ frame = rffi.cast(jitframe.JITFRAMEPTR, i - ofs)
+ frames.append(frame)
+ assert len(frame.jf_frame) == JITFRAME_FIXED_SIZE
+ # we "collect"
+ new_frame = frame.copy()
+ self.cpu.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
+ frame = rffi.cast(jitframe.JITFRAMEPTR, i - ofs)
+ assert frame == frames[1]
+ assert frame != frames[0]
+
+ 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,
+ EffectInfo.MOST_GENERAL)
+
+ loop = self.parse("""
[]
+ i0 = force_token() # this is a bit below the frame
+ call(ConstClass(check_adr), i0, descr=checkdescr) # this can collect
+ call(ConstClass(check2_adr), i0, descr=checkdescr)
finish(i0, descr=finaldescr)
- """, namespace={'finaldescr': BasicFinalDescr()})
+ """, namespace={'finaldescr': BasicFinalDescr(),
+ 'check_adr': checkptr, 'check2_adr': check2ptr,
+ 'checkdescr': checkdescr})
+ token = JitCellToken()
+ self.cpu.compile_loop(loop.inputargs, loop.operations, token)
+ frame = self.cpu.execute_token(token)
More information about the pypy-commit
mailing list