[pypy-commit] pypy shadowstack-again: in-progress: use r15 also to return exceptions
arigo
noreply at buildbot.pypy.org
Tue May 20 17:40:54 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: shadowstack-again
Changeset: r71602:35fc2a0ae50c
Date: 2014-05-20 17:40 +0200
http://bitbucket.org/pypy/pypy/changeset/35fc2a0ae50c/
Log: in-progress: use r15 also to return exceptions
diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py
--- a/rpython/memory/gctransform/shadowstack.py
+++ b/rpython/memory/gctransform/shadowstack.py
@@ -1,6 +1,7 @@
from rpython.flowspace.model import Block, Link, SpaceOperation
from rpython.annotator import model as annmodel
from rpython.translator.unsimplify import varoftype, copyvar
+from rpython.translator.backendopt.ssa import SSA_to_SSI
from rpython.rtyper.llannotation import SomePtr
from rpython.rlib.debug import ll_assert
from rpython.rlib.nonconst import NonConstant
@@ -16,38 +17,49 @@
class ShadowStackFrameworkGCTransformer(BaseFrameworkGCTransformer):
+ RPY_SHADOWSTACK_PTR = lltype.Ptr(
+ lltype.Struct('rpy_shadowstack_s',
+ hints={"external": "C", "c_name": "rpy_shadowstack_s"}))
+
def build_root_walker(self):
return ShadowStackRootWalker(self)
def transform_graph(self, graph):
self._transforming_graph = graph
+ self._ss_graph_marker = None
super(ShadowStackFrameworkGCTransformer, self).transform_graph(graph)
+ del self._ss_graph_marker
del self._transforming_graph
+ def sanitize_graph(self, graph):
+ SSA_to_SSI(graph, self.translator.annotator)
+
def ensure_ss_graph_marker(self):
- graph = self._transforming_graph
- ops = graph.startblock.operations
- if not ops or ops[0].opname != 'gc_ss_graph_marker':
+ if self._ss_graph_marker is None:
+ graph = self._transforming_graph
inputargs = [copyvar(self.translator.annotator, v)
for v in graph.startblock.inputargs]
- block = Block(inputargs)
- v_void = varoftype(lltype.Void)
- block.operations.append(SpaceOperation('gc_ss_graph_marker',
- [], v_void))
- block.closeblock(Link(inputargs, graph.startblock))
- graph.startblock = block
+ hblock = Block(inputargs)
+ v_marker = varoftype(self.RPY_SHADOWSTACK_PTR)
+ hblock.operations.append(SpaceOperation('gc_ss_graph_marker',
+ [], v_marker))
+ hblock.closeblock(Link(inputargs, graph.startblock))
+ graph.startblock = hblock
+ self._ss_graph_marker = v_marker
+ return self._ss_graph_marker
def push_roots(self, hop, keep_current_args=False):
livevars = self.get_livevars_for_roots(hop, keep_current_args)
self.num_pushs += len(livevars)
- self.ensure_ss_graph_marker()
- hop.genop("gc_ss_store", livevars)
+ v_marker = self.ensure_ss_graph_marker()
+ hop.genop("gc_ss_store", [v_marker] + livevars)
return livevars
def pop_roots(self, hop, livevars):
# for moving collectors, reload the roots into the local variables
if self.gcdata.gc.moving_gc and livevars:
- hop.genop("gc_ss_reload", livevars)
+ v_marker = self.ensure_ss_graph_marker()
+ hop.genop("gc_ss_reload", [v_marker] + livevars)
class ShadowStackRootWalker(BaseRootWalker):
diff --git a/rpython/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py
--- a/rpython/memory/gctransform/transform.py
+++ b/rpython/memory/gctransform/transform.py
@@ -247,6 +247,7 @@
old_startblock = graph.startblock
graph.startblock = graph.startblock.exits[0].target
+ self.sanitize_graph(graph)
checkgraph(graph)
self.links_to_split = None
@@ -257,6 +258,9 @@
graph.exc_cleanup = (v, list(llops))
return is_borrowed # xxx for tests only
+ def sanitize_graph(self, graph):
+ pass
+
def annotate_helper(self, ll_helper, ll_args, ll_result, inline=False):
assert not self.finished_helpers
args_s = map(lltype_to_annotation, ll_args)
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -438,6 +438,9 @@
'gc_gettypeptr_group': LLOp(canfold=True),
'get_member_index': LLOp(canfold=True),
+ 'getfield_exc_type': LLOp(sideeffects=False),
+ 'setfield_exc_type': LLOp(),
+
# __________ used by the JIT ________
'jit_marker': LLOp(),
diff --git a/rpython/translator/c/gc.py b/rpython/translator/c/gc.py
--- a/rpython/translator/c/gc.py
+++ b/rpython/translator/c/gc.py
@@ -444,22 +444,25 @@
return shadowstack.ShadowStackFrameworkGCTransformer(self.db.translator)
def OP_GC_SS_GRAPH_MARKER(self, funcgen, op):
- return '; struct rpy_shadowstack_s *rpy_ss = rpy_shadowstack;'
+ return '%s = rpy_shadowstack;' % funcgen.expr(op.result)
def OP_GC_SS_STORE(self, funcgen, op):
+ marker = funcgen.expr(op.args[0])
lines = []
- for i, v in enumerate(op.args):
- lines.append('rpy_ss[%d].s = %s;' % (i, funcgen.expr(v)))
- lines.append('rpy_shadowstack = rpy_ss + %d;' % len(op.args))
+ for i, v in enumerate(op.args[1:]):
+ lines.append('%s[%d].s = %s;' % (marker, i, funcgen.expr(v)))
+ lines.append('rpy_shadowstack = %s + %d;' % (marker, len(op.args)))
return '\n'.join(lines)
def OP_GC_SS_RELOAD(self, funcgen, op):
+ marker = funcgen.expr(op.args[0])
lines = []
- for i, v in enumerate(op.args):
+ for i, v in enumerate(op.args[1:]):
typename = funcgen.db.gettype(v.concretetype)
- lines.append('%s = (%s)rpy_ss[%d].s;' % (
+ lines.append('%s = (%s)%s[%d].s;' % (
funcgen.expr(v),
cdecl(typename, ''),
+ marker,
i))
if isinstance(v, Constant):
lines[-1] = '/* %s */' % lines[-1]
diff --git a/rpython/translator/c/src/entrypoint.c b/rpython/translator/c/src/entrypoint.c
--- a/rpython/translator/c/src/entrypoint.c
+++ b/rpython/translator/c/src/entrypoint.c
@@ -36,7 +36,6 @@
pypy_g_rpython_rtyper_lltypesystem_rffi_StackCounter.sc_inst_stacks_counter++;
#endif
instrument_setup();
- pypy_asm_stack_bottom();
#ifndef MS_WINDOWS
/* this message does no longer apply to win64 :-) */
@@ -50,14 +49,18 @@
errmsg = RPython_StartupCode();
if (errmsg) goto error;
+ pypy_asm_stack_bottom();
list = _RPyListOfString_New(argc);
if (RPyExceptionOccurred()) goto memory_out;
for (i=0; i<argc; i++) {
+ pypy_asm_stack_bottom();
RPyString *s = RPyString_FromString(argv[i]);
if (RPyExceptionOccurred()) goto memory_out;
+ pypy_asm_stack_bottom();
_RPyListOfString_SetItem(list, i, s);
}
+ pypy_asm_stack_bottom();
exitcode = STANDALONE_ENTRY_POINT(list);
pypy_debug_alloc_results();
diff --git a/rpython/translator/c/src/mem.h b/rpython/translator/c/src/mem.h
--- a/rpython/translator/c/src/mem.h
+++ b/rpython/translator/c/src/mem.h
@@ -224,5 +224,18 @@
pypy_g_rpython_memory_gctypelayout_GCData.gcd_inst_root_stack_top = s;
}
+#define OP_GETFIELD_EXC_TYPE(r) \
+ if (__builtin_expect(((Signed)rpy_shadowstack) & 1, 0)) { \
+ r = (struct pypy_object_vtable0 *)(((char *)rpy_shadowstack) - 1); \
+ if (!r) __builtin_unreachable(); \
+ } \
+ else { \
+ r = NULL; \
+ }
+#define OP_SETFIELD_EXC_TYPE(x, r) \
+ rpy_shadowstack = (x) ? \
+ (struct rpy_shadowstack_s *)(((char *)x) + 1) \
+ : NULL
+
#endif
diff --git a/rpython/translator/exceptiontransform.py b/rpython/translator/exceptiontransform.py
--- a/rpython/translator/exceptiontransform.py
+++ b/rpython/translator/exceptiontransform.py
@@ -67,17 +67,19 @@
self.c_n_i_error_ll_exc_type = constant_value(n_i_error_ll_exc_type)
def rpyexc_occured():
- exc_type = exc_data.exc_type
+ exc_type = lloperation.llop.getfield_exc_type(
+ self.lltype_of_exception_type)
return bool(exc_type)
def rpyexc_fetch_type():
- return exc_data.exc_type
+ return lloperation.llop.getfield_exc_type(
+ self.lltype_of_exception_type)
def rpyexc_fetch_value():
return exc_data.exc_value
def rpyexc_clear():
- exc_data.exc_type = null_type
+ lloperation.llop.setfield_exc_type(lltype.Void, null_type)
exc_data.exc_value = null_value
def rpyexc_raise(etype, evalue):
@@ -90,12 +92,12 @@
# us to see at least part of the traceback for them.
ll_assert(etype != assertion_error_ll_exc_type, "AssertionError")
ll_assert(etype != n_i_error_ll_exc_type, "NotImplementedError")
- exc_data.exc_type = etype
+ lloperation.llop.setfield_exc_type(lltype.Void, etype)
exc_data.exc_value = evalue
lloperation.llop.debug_start_traceback(lltype.Void, etype)
def rpyexc_reraise(etype, evalue):
- exc_data.exc_type = etype
+ lloperation.llop.setfield_exc_type(lltype.Void, etype)
exc_data.exc_value = evalue
lloperation.llop.debug_reraise_traceback(lltype.Void, etype)
@@ -106,7 +108,8 @@
def rpyexc_restore_exception(evalue):
if evalue:
- exc_data.exc_type = ll_inst_type(evalue)
+ lloperation.llop.setfield_exc_type(lltype.Void,
+ ll_inst_type(evalue))
exc_data.exc_value = evalue
self.rpyexc_occured_ptr = self.build_func(
@@ -143,15 +146,15 @@
lltype.Void,
jitcallkind='rpyexc_raise') # for the JIT
- self.rpyexc_fetch_exception_ptr = self.build_func(
- "RPyFetchException",
- rpyexc_fetch_exception,
- [], self.lltype_of_exception_value)
+ #self.rpyexc_fetch_exception_ptr = self.build_func(
+ # "RPyFetchException",
+ # rpyexc_fetch_exception,
+ # [], self.lltype_of_exception_value)
- self.rpyexc_restore_exception_ptr = self.build_func(
- "RPyRestoreException",
- self.noinline(rpyexc_restore_exception),
- [self.lltype_of_exception_value], lltype.Void)
+ #self.rpyexc_restore_exception_ptr = self.build_func(
+ # "RPyRestoreException",
+ # self.noinline(rpyexc_restore_exception),
+ # [self.lltype_of_exception_value], lltype.Void)
self.build_extra_funcs()
@@ -461,7 +464,6 @@
def setup_excdata(self):
EXCDATA = lltype.Struct('ExcData',
- ('exc_type', self.lltype_of_exception_type),
('exc_value', self.lltype_of_exception_value))
self.EXCDATA = EXCDATA
@@ -482,11 +484,17 @@
return Constant(fn_ptr, lltype.Ptr(FUNC_TYPE))
def gen_getfield(self, name, llops):
+ if name == 'exc_type':
+ return llops.genop('getfield_exc_type', [],
+ resulttype = self.lltype_of_exception_type)
c_name = inputconst(lltype.Void, name)
return llops.genop('getfield', [self.cexcdata, c_name],
resulttype = getattr(self.EXCDATA, name))
def gen_setfield(self, name, v_value, llops):
+ if name == 'exc_type':
+ llops.genop('setfield_exc_type', [v_value])
+ return
c_name = inputconst(lltype.Void, name)
llops.genop('setfield', [self.cexcdata, c_name, v_value])
@@ -515,6 +523,7 @@
exc_data = self.exc_data_ptr
def rpyexc_get_exception_addr():
+ raise NotImplementedError
return (llmemory.cast_ptr_to_adr(exc_data) +
llmemory.offsetof(EXCDATA, 'exc_type'))
More information about the pypy-commit
mailing list