Author: Armin Rigo <ar...@tunes.org>
Branch: shadowstack-again
Changeset: r71600:77dafb290569
Date: 2014-05-20 15:21 +0200
http://bitbucket.org/pypy/pypy/changeset/77dafb290569/

Log:    Starting

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,4 +1,6 @@
+from rpython.flowspace.model import Block, Link, SpaceOperation
 from rpython.annotator import model as annmodel
+from rpython.translator.unsimplify import varoftype, copyvar
 from rpython.rtyper.llannotation import SomePtr
 from rpython.rlib.debug import ll_assert
 from rpython.rlib.nonconst import NonConstant
@@ -13,46 +15,38 @@
 
 
 class ShadowStackFrameworkGCTransformer(BaseFrameworkGCTransformer):
-    def annotate_walker_functions(self, getfn):
-        self.incr_stack_ptr = getfn(self.root_walker.incr_stack,
-                                   [annmodel.SomeInteger()],
-                                   SomeAddress(),
-                                   inline = True)
-        self.decr_stack_ptr = getfn(self.root_walker.decr_stack,
-                                   [annmodel.SomeInteger()],
-                                   SomeAddress(),
-                                   inline = True)
-
     def build_root_walker(self):
         return ShadowStackRootWalker(self)
 
+    def transform_graph(self, graph):
+        self._transforming_graph = graph
+        super(ShadowStackFrameworkGCTransformer, self).transform_graph(graph)
+        del self._transforming_graph
+
+    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':
+            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
+
     def push_roots(self, hop, keep_current_args=False):
         livevars = self.get_livevars_for_roots(hop, keep_current_args)
         self.num_pushs += len(livevars)
-        if not livevars:
-            return []
-        c_len = rmodel.inputconst(lltype.Signed, len(livevars) )
-        base_addr = hop.genop("direct_call", [self.incr_stack_ptr, c_len ],
-                              resulttype=llmemory.Address)
-        for k,var in enumerate(livevars):
-            c_k = rmodel.inputconst(lltype.Signed, k * sizeofaddr)
-            v_adr = gen_cast(hop.llops, llmemory.Address, var)
-            hop.genop("raw_store", [base_addr, c_k, v_adr])
+        self.ensure_ss_graph_marker()
+        hop.genop("gc_ss_store", livevars)
         return livevars
 
     def pop_roots(self, hop, livevars):
-        if not livevars:
-            return
-        c_len = rmodel.inputconst(lltype.Signed, len(livevars) )
-        base_addr = hop.genop("direct_call", [self.decr_stack_ptr, c_len ],
-                              resulttype=llmemory.Address)
-        if self.gcdata.gc.moving_gc:
-            # for moving collectors, reload the roots into the local variables
-            for k,var in enumerate(livevars):
-                c_k = rmodel.inputconst(lltype.Signed, k * sizeofaddr)
-                v_newaddr = hop.genop("raw_load", [base_addr, c_k],
-                                      resulttype=llmemory.Address)
-                hop.genop("gc_reload_possibly_moved", [v_newaddr, var])
+        # for moving collectors, reload the roots into the local variables
+        if self.gcdata.gc.moving_gc and livevars:
+            hop.genop("gc_ss_reload", livevars)
 
 
 class ShadowStackRootWalker(BaseRootWalker):
@@ -61,18 +55,6 @@
         # NB. 'self' is frozen, but we can use self.gcdata to store state
         gcdata = self.gcdata
 
-        def incr_stack(n):
-            top = gcdata.root_stack_top
-            gcdata.root_stack_top = top + n*sizeofaddr
-            return top
-        self.incr_stack = incr_stack
-
-        def decr_stack(n):
-            top = gcdata.root_stack_top - n*sizeofaddr
-            gcdata.root_stack_top = top
-            return top
-        self.decr_stack = decr_stack
-
         root_iterator = get_root_iterator(gctransformer)
         def walk_stack_root(callback, start, end):
             root_iterator.setcontext(NonConstant(llmemory.NULL))
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
@@ -465,7 +465,9 @@
     'gc_restore_exception': LLOp(),
     'gc_call_rtti_destructor': LLOp(),
     'gc_deallocate':        LLOp(),
-    'gc_reload_possibly_moved': LLOp(),
+    'gc_ss_graph_marker':   LLOp(),
+    'gc_ss_store':          LLOp(),
+    'gc_ss_reload':         LLOp(),
     # see rlib/objectmodel for gc_identityhash and gc_id
     'gc_identityhash':      LLOp(sideeffects=False, canmallocgc=True),
     'gc_id':                LLOp(sideeffects=False, canmallocgc=True),
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
@@ -437,6 +437,29 @@
         from rpython.memory.gctransform import shadowstack
         return 
shadowstack.ShadowStackFrameworkGCTransformer(self.db.translator)
 
+    def OP_GC_SS_GRAPH_MARKER(self, funcgen, op):
+        return '; struct rpy_shadowstack_s *rpy_ss = rpy_shadowstack;'
+
+    def OP_GC_SS_STORE(self, funcgen, op):
+        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))
+        return '\n'.join(lines)
+
+    def OP_GC_SS_RELOAD(self, funcgen, op):
+        lines = []
+        for i, v in enumerate(op.args):
+            typename = funcgen.db.gettype(v.concretetype)
+            lines.append('%s = (%s)rpy_ss[%d].s;' % (
+                funcgen.expr(v),
+                cdecl(typename, ''),
+                i))
+            if isinstance(v, Constant):
+                lines[-1] = '/* %s */' % lines[-1]
+        lines.reverse()
+        return '\n'.join(lines)
+
 class AsmGcRootFrameworkGcPolicy(BasicFrameworkGcPolicy):
 
     def gettransformer(self):
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
@@ -35,7 +35,6 @@
 #ifdef PYPY_USE_ASMGCC
     
pypy_g_rpython_rtyper_lltypesystem_rffi_StackCounter.sc_inst_stacks_counter++;
 #endif
-    pypy_asm_stack_bottom();
     instrument_setup();
 
 #ifndef MS_WINDOWS
@@ -50,6 +49,7 @@
     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++) {
diff --git a/rpython/translator/c/src/mem.c b/rpython/translator/c/src/mem.c
--- a/rpython/translator/c/src/mem.c
+++ b/rpython/translator/c/src/mem.c
@@ -95,7 +95,14 @@
     GC_finalize_on_demand = 1;
     GC_set_warn_proc(mem_boehm_ignore);
 }
-#endif /* BOEHM GC */
+
+#elif !defined(PYPY_USE_ASMGCC)     /* shadowstack */
+
+#ifndef RPY_SHADOWSTACK_REG
+struct rpy_shadowstack_s *rpy_shadowstack;
+#endif
+
+#endif /* BOEHM_GC / PYPY_USE_ASMGCC */
 
 
 #ifdef RPY_ASSERT
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
@@ -136,12 +136,13 @@
 #define OP_GC_DUMP_RPY_HEAP(fd, r)       r = 0
 #define OP_GC_SET_EXTRA_THRESHOLD(x, r)  /* nothing */
 
+
+#ifdef PYPY_USE_ASMGCC
 /****************************/
 /* The "asmgcc" root finder */
 /****************************/
 
-#ifndef _MSC_VER
-/* Implementation for Linux */
+/* Implementation of asmgcc, for Linux only */
 extern char __gcmapstart;
 extern char __gcmapend;
 extern char __gccallshapes;
@@ -194,44 +195,27 @@
        i == 2 ? (void*)&__gccallshapes :              \
        NULL
 
+
 #else
-/* implementation of asmgcroot for Windows */
-extern void* __gcmapstart;
-extern void* __gcmapend;
-extern char* __gccallshapes;
-extern Signed pypy_asm_stackwalk(void*, void*);
+/*********************************/
+/* The "shadowstack" root finder */
+/*********************************/
 
-/* With the msvc Microsoft Compiler, the optimizer seems free to move
-   any code (even asm) that involves local memory (registers and stack).
-   The _ReadWriteBarrier function has an effect only where the content
-   of a global variable is *really* used.  trackgcroot.py will remove
-   the extra instructions: the access to _constant_always_one_ is
-   removed, and the multiplication is replaced with a simple move. */
+#if defined(__GNUC__) && defined(__amd64__)
+#  define RPY_SHADOWSTACK_REG  "r15"
+#endif
 
-static __forceinline void*
-pypy_asm_gcroot(void* _r1)
+struct rpy_shadowstack_s { void *s; };
+#ifdef RPY_SHADOWSTACK_REG
+register struct rpy_shadowstack_s *rpy_shadowstack asm(RPY_SHADOWSTACK_REG);
+#else
+extern struct rpy_shadowstack_s *rpy_shadowstack;
+#endif
+
+static inline void pypy_asm_stack_bottom(void)
 {
-    static volatile int _constant_always_one_ = 1;
-    (Signed)_r1 *= _constant_always_one_;
-    _ReadWriteBarrier();
-    return _r1;
+    abort();
 }
 
-#define pypy_asm_gc_nocollect(f) "/* GC_NOCOLLECT " #f " */"
-
-#ifndef _WIN64
-#  define pypy_asm_keepalive(v)    __asm { }
-#else
-   /* is there something cheaper? */
-#  define pypy_asm_keepalive(v)    _ReadWriteBarrier();
-#endif
-
-static __declspec(noinline) void pypy_asm_stack_bottom() { }
-
-#define OP_GC_ASMGCROOT_STATIC(i, r)                  \
-    r =        i == 0 ? (void*)__gcmapstart :                 \
-       i == 1 ? (void*)__gcmapend :                   \
-       i == 2 ? (void*)&__gccallshapes :              \
-       NULL
 
 #endif
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to