Commits

Armin Rigo  committed f2bf949

Tweaks.

  • Participants
  • Parent commits 2494530
  • Branches shadowstack-perf

Comments (0)

Files changed (3)

File pypy/rlib/register.py

 eci = ExternalCompilationInfo(
     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_GET_SPECIAL_REG_NOMARK() ((void *)pypy_r15)
+#define PYPY_SET_SPECIAL_REG_NOMARK(x) (pypy_r15 = (long)(x))
+#define PYPY_GET_SPECIAL_REG_MARK() ((void *)(pypy_r15 & ~1))
+#define PYPY_INCR_SPECIAL_REG_MARK(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)
 """],
     _value_reg = None
     _exc_marker = False
 
-    def _pypy_get_special_reg():
+    def _pypy_get_special_reg_nomark():
+        # this must not be called if _exc_marker is set
+        assert _value_reg is not None
+        assert not _exc_marker
+        return _value_reg
+
+    def _pypy_set_special_reg_nomark(addr):
+        # this must not be called if _exc_marker is set
+        global _value_reg
+        assert not _exc_marker
+        _value_reg = addr
+
+    def _pypy_get_special_reg_mark():
+        # this can be called if _exc_marker is set
         assert _value_reg is not None
         return _value_reg
 
-    def _pypy_set_special_reg(addr):
-        global _value_reg
-        _value_reg = addr
-
-    def _pypy_incr_special_reg(delta):
+    def _pypy_incr_special_reg_mark(delta):
+        # this can be called if _exc_marker is set
         global _value_reg
         assert _value_reg is not None
         _value_reg += delta
         global _value_reg
         _exc_marker = flag
 
-    load_from_reg = rffi.llexternal('PYPY_GET_SPECIAL_REG', [],
-                                    llmemory.Address,
-                                    _callable=_pypy_get_special_reg,
+    load_from_reg_nomark = rffi.llexternal('PYPY_GET_SPECIAL_REG_NOMARK', [],
+                                           llmemory.Address,
+                                        _callable=_pypy_get_special_reg_nomark,
+                                           compilation_info=eci,
+                                           _nowrapper=True)
+
+    store_into_reg_nomark = rffi.llexternal('PYPY_SET_SPECIAL_REG_NOMARK',
+                                            [llmemory.Address],
+                                            lltype.Void,
+                                        _callable=_pypy_set_special_reg_nomark,
+                                            compilation_info=eci,
+                                            _nowrapper=True)
+
+    load_from_reg_mark = rffi.llexternal('PYPY_GET_SPECIAL_REG_MARK', [],
+                                         llmemory.Address,
+                                         _callable=_pypy_get_special_reg_mark,
+                                         compilation_info=eci,
+                                         _nowrapper=True)
+
+    incr_reg_mark = rffi.llexternal('PYPY_INCR_SPECIAL_REG_MARK',
+                                    [lltype.Signed],
+                                    lltype.Void,
+                                    _callable=_pypy_incr_special_reg_mark,
                                     compilation_info=eci,
                                     _nowrapper=True)
 
-    store_into_reg = rffi.llexternal('PYPY_SET_SPECIAL_REG',
-                                     [llmemory.Address],
-                                     lltype.Void,
-                                     _callable=_pypy_set_special_reg,
-                                     compilation_info=eci,
-                                     _nowrapper=True)
-
-    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,

File pypy/rpython/memory/gctransform/framework.py

 
         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)
         # for tests
         self.frameworkgc__teardown_ptr = getfn(frameworkgc__teardown, [],
                                                annmodel.s_None)
-        
-        if root_walker.need_root_stack:
-            self.get_stack_top_ptr = getfn(root_walker.get_stack_top,
-                                           [], annmodel.SomeAddress(),
-                                           inline = True)
-            self.set_stack_top_ptr = getfn(root_walker.set_stack_top,
-                                           [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)
         
         return livevars
 
     def push_roots(self, hop, keep_current_args=False):
-        if self.get_stack_top_ptr is None:
+        if not self.root_walker.need_root_stack:
             return
         livevars = self.get_livevars_for_roots(hop, keep_current_args)
         if livevars:
         return livevars
 
     def pop_roots(self, hop, livevars):
-        if self.get_stack_top_ptr is None:
+        if not self.root_walker.need_root_stack:
             return
         if livevars:
             hop.genop("gc_pop_roots", livevars)

File pypy/rpython/memory/gctransform/shadowstack.py

         gcdata = self.gcdata
 
         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
+            self.get_stack_top_nomark = register.load_from_reg_nomark
+            self.get_stack_top = register.load_from_reg_mark
+            self.set_stack_top = register.store_into_reg_nomark
+            self.incr_stack_top = register.incr_reg_mark
+            for name in ['get_stack_top_nomark',
+                         'get_stack_top',
+                         'set_stack_top',
+                         'incr_stack_top']:
+                fptr = getattr(self, name)
+                c = Constant(fptr, lltype.typeOf(fptr))
+                setattr(self, name + '_ptr', c)
         else:
             def get_stack_top():
                 return gcdata.root_stack_top
                 gcdata.root_stack_top += delta
             self.incr_stack_top = incr_stack_top
 
+            self.get_stack_top_ptr = getfn(root_walker.get_stack_top,
+                                           [], annmodel.SomeAddress(),
+                                           inline = True)
+            self.set_stack_top_ptr = getfn(root_walker.set_stack_top,
+                                           [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)
+            self.get_stack_top_nomark_ptr = self.get_stack_top_ptr
+
         self.rootstackhook = gctransformer.root_stack_jit_hook
         if self.rootstackhook is None:
             def collect_stack_root(callback, gc, addr):
                                                       c_k, v])
                     else:
                         v_topaddr = llops.genop("direct_call",
-                                                [gct.get_stack_top_ptr],
+                                                [self.get_stack_top_ptr],
                                                 resulttype=llmemory.Address)
                         v_newaddr = llops.genop("raw_load",
                                                 [v_topaddr, c_type, c_k],
             if "stop" in blockstate[block]:     # "stop" or "startstop"
                 llops = LowLevelOpList()
                 i = blocks_pop_roots[block]
-                llops.genop("direct_call", [gct.incr_stack_top_ptr,
+                llops.genop("direct_call", [self.incr_stack_top_ptr,
                                             c_minusframesize])
                 block.operations[i:i] = llops
                 # ^^^ important: done first, in case it's a startstop block,
             if "start" in blockstate[block]:    # "start" or "startstop"
                 llops = LowLevelOpList()
                 v_topaddr = get_v_topaddr(block)
-                v_baseaddr = llops.genop("direct_call",[gct.get_stack_top_ptr],
+                v_baseaddr = llops.genop("direct_call",
+                                         [self.get_stack_top_nomark_ptr],
                                          resulttype=llmemory.Address)
                 llops.genop("adr_add", [v_baseaddr, c_framesize])
                 llops[-1].result = v_topaddr
-                llops.genop("direct_call", [gct.set_stack_top_ptr, v_topaddr])
+                llops.genop("direct_call", [self.set_stack_top_ptr, v_topaddr])
                 c_null = rmodel.inputconst(llmemory.Address, llmemory.NULL)
                 for k in range(numcolors):
                     c_k = rmodel.inputconst(lltype.Signed, ~k)
                     # we need to get the current stack top for this block
                     i, topaddr_v = topaddrs_v[block]
                     llops = LowLevelOpList()
-                    llops.genop("direct_call", [gct.get_stack_top_ptr])
+                    llops.genop("direct_call", [self.get_stack_top_nomark_ptr])
                     llops[-1].result = topaddr_v
                     block.operations[i:i] = llops
         #