[pypy-commit] pypy shadowstack-perf: Start to integrate the r15-for-exception branch...
arigo
noreply at buildbot.pypy.org
Sun Sep 4 12:12:39 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: shadowstack-perf
Changeset: r47065:249453097f4f
Date: 2011-09-04 10:20 +0200
http://bitbucket.org/pypy/pypy/changeset/249453097f4f/
Log: Start to integrate the r15-for-exception branch...
diff --git a/pypy/rlib/register.py b/pypy/rlib/register.py
--- a/pypy/rlib/register.py
+++ b/pypy/rlib/register.py
@@ -15,18 +15,20 @@
# For now, only for x86-64. Tries to use the register r15.
eci = ExternalCompilationInfo(
- post_include_bits=[
- 'register void *pypy_r15 asm("r15");\n'
- '#define PYPY_GET_SPECIAL_REG() pypy_r15\n'
- '#define PYPY_SPECIAL_REG_NONNULL() (pypy_r15 != NULL)\n'
- '#define PYPY_SET_SPECIAL_REG(x) (pypy_r15 = x)\n'
- ],
+ post_include_bits=["""
+register long pypy_r15 asm("r15");
+#define PYPY_GET_SPECIAL_REG() ((void *)(pypy_r15 & ~1))
+#define PYPY_SET_SPECIAL_REG(x) (pypy_r15 = (long)(x) | (pypy_r15 & 1))
+#define PYPY_INCR_SPECIAL_REG(d) (pypy_r15 += (d))
+#define PYPY_SPECIAL_REG_GETEXC() (pypy_r15 & 1)
+#define PYPY_SPECIAL_REG_SETEXC(x) (pypy_r15 = (x) ? pypy_r15|1 : pypy_r15&~1)
+"""],
)
_test_eci = eci.merge(ExternalCompilationInfo(
post_include_bits=["""
void f(void) {
- pypy_r15 = &f;
+ pypy_r15 = 12345;
}
"""]))
@@ -45,31 +47,34 @@
# the behavior is emulated.
_value_reg = None
+ _exc_marker = False
def _pypy_get_special_reg():
assert _value_reg is not None
return _value_reg
- def _pypy_special_reg_nonnull():
- assert _value_reg is not None
- return bool(_value_reg)
-
def _pypy_set_special_reg(addr):
global _value_reg
_value_reg = addr
+ def _pypy_incr_special_reg(delta):
+ global _value_reg
+ assert _value_reg is not None
+ _value_reg += delta
+
+ def _pypy_special_reg_getexc():
+ return _exc_marker
+
+ def _pypy_special_reg_setexc(flag):
+ global _value_reg
+ _exc_marker = flag
+
load_from_reg = rffi.llexternal('PYPY_GET_SPECIAL_REG', [],
llmemory.Address,
_callable=_pypy_get_special_reg,
compilation_info=eci,
_nowrapper=True)
- reg_is_nonnull = rffi.llexternal('PYPY_SPECIAL_REG_NONNULL', [],
- lltype.Bool,
- _callable=_pypy_special_reg_nonnull,
- compilation_info=eci,
- _nowrapper=True)
-
store_into_reg = rffi.llexternal('PYPY_SET_SPECIAL_REG',
[llmemory.Address],
lltype.Void,
@@ -77,5 +82,21 @@
compilation_info=eci,
_nowrapper=True)
- # xxx temporary
- nonnull = llmemory.cast_int_to_adr(-1)
+ incr_reg = rffi.llexternal('PYPY_INCR_SPECIAL_REG',
+ [lltype.Signed],
+ lltype.Void,
+ _callable=_pypy_set_special_reg,
+ compilation_info=eci,
+ _nowrapper=True)
+
+ get_exception = rffi.llexternal('PYPY_SPECIAL_REG_GETEXC', [],
+ lltype.Bool,
+ _callable=_pypy_special_reg_getexc,
+ compilation_info=eci,
+ _nowrapper=True)
+
+ set_exception = rffi.llexternal('PYPY_SPECIAL_REG_SETEXC', [lltype.Bool],
+ lltype.Void,
+ _callable=_pypy_special_reg_setexc,
+ compilation_info=eci,
+ _nowrapper=True)
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -229,6 +229,11 @@
def getfn(ll_function, args_s, s_result, inline=False,
minimal_transform=True):
+ if isinstance(ll_function, lltype._ptr):
+ # assume that args_s and s_result match
+ from pypy.objspace.flow.model import Constant
+ return Constant(ll_function, lltype.typeOf(ll_function))
+ #
graph = annhelper.getgraph(ll_function, args_s, s_result)
if minimal_transform:
self.need_minimal_transform(graph)
@@ -250,9 +255,14 @@
[annmodel.SomeAddress()],
annmodel.s_None,
inline = True)
+ self.incr_stack_top_ptr = getfn(root_walker.incr_stack_top,
+ [annmodel.SomeInteger()],
+ annmodel.s_None,
+ inline = True)
else:
self.get_stack_top_ptr = None
self.set_stack_top_ptr = None
+ self.incr_stack_top_ptr = None
self.weakref_deref_ptr = self.inittime_helper(
ll_weakref_deref, [llmemory.WeakRefPtr], llmemory.Address)
diff --git a/pypy/rpython/memory/gctransform/shadowstack.py b/pypy/rpython/memory/gctransform/shadowstack.py
--- a/pypy/rpython/memory/gctransform/shadowstack.py
+++ b/pypy/rpython/memory/gctransform/shadowstack.py
@@ -2,6 +2,7 @@
from pypy.rpython.memory.gctransform.framework import BaseRootWalker
from pypy.rpython.memory.gctransform.framework import sizeofaddr
from pypy.rpython import rmodel
+from pypy.rlib import register
from pypy.rlib.debug import ll_assert
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.tool.algo.regalloc import perform_register_allocation
@@ -22,13 +23,20 @@
# NB. 'self' is frozen, but we can use self.gcdata to store state
gcdata = self.gcdata
- def get_stack_top():
- return gcdata.root_stack_top
- self.get_stack_top = get_stack_top
-
- def set_stack_top(addr):
- gcdata.root_stack_top = addr
- self.set_stack_top = set_stack_top
+ if register.register_number is not None:
+ self.get_stack_top = register.load_from_reg
+ self.set_stack_top = register.store_into_reg
+ self.incr_stack_top = register.incr_reg
+ else:
+ def get_stack_top():
+ return gcdata.root_stack_top
+ self.get_stack_top = get_stack_top
+ def set_stack_top(addr):
+ gcdata.root_stack_top = addr
+ self.set_stack_top = set_stack_top
+ def incr_stack_top(delta):
+ gcdata.root_stack_top += delta
+ self.incr_stack_top = incr_stack_top
self.rootstackhook = gctransformer.root_stack_jit_hook
if self.rootstackhook is None:
@@ -40,12 +48,12 @@
def push_stack(self, addr):
top = self.get_stack_top()
+ self.incr_stack_top(sizeofaddr)
top.address[0] = addr
- self.set_stack_top(top + sizeofaddr)
def pop_stack(self):
top = self.get_stack_top() - sizeofaddr
- self.set_stack_top(top)
+ self.incr_stack_top(-sizeofaddr)
return top.address[0]
def allocate_stack(self):
@@ -54,7 +62,7 @@
def setup_root_walker(self):
stackbase = self.allocate_stack()
ll_assert(bool(stackbase), "could not allocate root stack")
- self.gcdata.root_stack_top = stackbase
+ self.set_stack_top(stackbase)
self.gcdata.root_stack_base = stackbase
BaseRootWalker.setup_root_walker(self)
@@ -63,7 +71,7 @@
gc = self.gc
rootstackhook = self.rootstackhook
addr = gcdata.root_stack_base
- end = gcdata.root_stack_top
+ end = self.get_stack_top()
while addr != end:
addr += rootstackhook(collect_stack_root, gc, addr)
if self.collect_stacks_from_other_threads is not None:
@@ -307,7 +315,9 @@
blocks_pop_roots[block] = len(llops)
block.operations[:] = llops
numcolors = -negnumcolors
- c_framesize = rmodel.inputconst(lltype.Signed, numcolors * sizeofaddr)
+ framesize = numcolors * sizeofaddr
+ c_framesize = rmodel.inputconst(lltype.Signed, framesize)
+ c_minusframesize = rmodel.inputconst(lltype.Signed, -framesize)
#
# For each block, determine in which category it is:
#
@@ -399,10 +409,8 @@
if "stop" in blockstate[block]: # "stop" or "startstop"
llops = LowLevelOpList()
i = blocks_pop_roots[block]
- v_topaddr = get_v_topaddr(block, firstuse=i)
- v_baseaddr = llops.genop("adr_sub", [v_topaddr, c_framesize],
- resulttype=llmemory.Address)
- llops.genop("direct_call", [gct.set_stack_top_ptr, v_baseaddr])
+ llops.genop("direct_call", [gct.incr_stack_top_ptr,
+ c_minusframesize])
block.operations[i:i] = llops
# ^^^ important: done first, in case it's a startstop block,
# otherwise the index in 'blocks_push_roots[block]' is
diff --git a/pypy/translator/c/src/mem.h b/pypy/translator/c/src/mem.h
--- a/pypy/translator/c/src/mem.h
+++ b/pypy/translator/c/src/mem.h
@@ -87,7 +87,7 @@
#ifdef PYPY_GET_SPECIAL_REG /* pypy/rlib/register.py */
# define OP_GC_STACK_BOTTOM(r) pypy_asm_stack_bottom(); \
r = PYPY_GET_SPECIAL_REG(); \
- PYPY_SET_SPECIAL_REG((void*)-1)
+ PYPY_SPECIAL_REG_SETEXC(0)
# define OP_GC_STACK_BOTTOM_STOP(v,r) PYPY_SET_SPECIAL_REG(v)
#else
# define OP_GC_STACK_BOTTOM(r) pypy_asm_stack_bottom()
diff --git a/pypy/translator/exceptiontransform.py b/pypy/translator/exceptiontransform.py
--- a/pypy/translator/exceptiontransform.py
+++ b/pypy/translator/exceptiontransform.py
@@ -77,15 +77,12 @@
use_special_reg = standalone and register.register_number is not None
self.use_special_reg = use_special_reg
if use_special_reg:
- self.c_nonnull_specialregister = constant_value(register.nonnull)
- self.c_load_from_reg = constant_value(register.load_from_reg)
- self.c_reg_is_nonnull = constant_value(register.reg_is_nonnull)
- self.c_store_into_reg = constant_value(register.store_into_reg)
+ self.c_get_exception = constant_value(register.get_exception)
+ self.c_set_exception = constant_value(register.set_exception)
def rpyexc_occured():
if use_special_reg:
- # an exception occurred iff the special register is 0
- return register.load_from_reg() == llmemory.NULL
+ return register.get_exception()
else:
exc_type = exc_data.exc_type
return bool(exc_type)
@@ -98,7 +95,7 @@
def rpyexc_clear():
if use_special_reg:
- register.store_into_reg(register.nonnull)
+ register.set_exception(False)
exc_data.exc_type = null_type
exc_data.exc_value = null_value
@@ -116,14 +113,14 @@
exc_data.exc_value = evalue
lloperation.llop.debug_start_traceback(lltype.Void, etype)
if use_special_reg:
- register.store_into_reg(llmemory.NULL)
+ register.set_exception(True)
def rpyexc_reraise(etype, evalue):
exc_data.exc_type = etype
exc_data.exc_value = evalue
lloperation.llop.debug_reraise_traceback(lltype.Void, etype)
if use_special_reg:
- register.store_into_reg(llmemory.NULL)
+ register.set_exception(True)
def rpyexc_fetch_exception():
evalue = rpyexc_fetch_value()
@@ -135,7 +132,7 @@
exc_data.exc_type = rclass.ll_inst_type(evalue)
exc_data.exc_value = evalue
if use_special_reg:
- register.store_into_reg(llmemory.NULL)
+ register.set_exception(True)
def rpyexc_raise_stack_overflow():
rpyexc_raise(stackovf_ll_exc_type, stackovf_ll_exc)
@@ -432,7 +429,7 @@
self.gen_setfield('exc_value', self.c_null_evalue, llops)
self.gen_setfield('exc_type', self.c_null_etype, llops)
if self.use_special_reg:
- self.gen_setspecialregister(self.c_nonnull_specialregister, llops)
+ self.gen_setexception(False, llops)
excblock.operations[:] = llops
newgraph.exceptblock.inputargs[0].concretetype = self.lltype_of_exception_type
newgraph.exceptblock.inputargs[1].concretetype = self.lltype_of_exception_value
@@ -553,16 +550,14 @@
def gen_nonnull(self, v, llops):
return llops.genop('ptr_nonzero', [v], lltype.Bool)
- def gen_getspecialregister(self, llops):
- return llops.genop('direct_call', [self.c_load_from_reg],
- resulttype = llmemory.Address)
+ def gen_specialreg_no_exc(self, llops):
+ v = llops.genop('direct_call', [self.c_get_exception],
+ resulttype = lltype.Bool)
+ return llops.genop('bool_not', [v], resulttype=lltype.Bool)
- def gen_specialreg_no_exc(self, llops):
- return llops.genop('direct_call', [self.c_reg_is_nonnull],
- resulttype = lltype.Bool)
-
- def gen_setspecialregister(self, v, llops):
- llops.genop('direct_call', [self.c_store_into_reg, v])
+ def gen_setexception(self, flag, llops):
+ v = inputconst(lltype.Bool, flag)
+ llops.genop('direct_call', [self.c_set_exception, v])
def same_obj(self, ptr1, ptr2):
return ptr1._same_obj(ptr2)
More information about the pypy-commit
mailing list