Author: Armin Rigo <ar...@tunes.org>
Branch: shadowstack-perf-2
Changeset: r90557:39add7b84e2a
Date: 2017-03-05 10:50 +0100
http://bitbucket.org/pypy/pypy/changeset/39add7b84e2a/

Log:    Properly emulate gc_enter_roots_frame() & co. inside the llinterp.

diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -1087,17 +1087,57 @@
         checkadr(addr)
 
     def op_gc_enter_roots_frame(self, gcdata, numcolors):
+        """Fetch from the gcdata the current root_stack_top; bump it
+        by 'numcolors'; and assert that the new area is fully
+        uninitialized so far.
+        """
         assert not hasattr(self, '_inside_roots_frame')
-        self._inside_roots_frame = numcolors
+        p = gcdata.inst_root_stack_top.ptr
+        q = lltype.direct_ptradd(p, numcolors)
+        self._inside_roots_frame = (p, q, numcolors, gcdata)
+        gcdata.inst_root_stack_top = llmemory.cast_ptr_to_adr(q)
+        #
+        array = p._obj._parentstructure()
+        index = p._obj._parent_index
+        for i in range(index, index + numcolors):
+            assert isinstance(array.getitem(i), lltype._uninitialized)
 
     def op_gc_leave_roots_frame(self):
+        """Cancel gc_enter_roots_frame() by removing the frame from
+        the root_stack_top.  Writes uninitialized entries in its old place.
+        """
+        (p, q, numcolors, gcdata) = self._inside_roots_frame
+        assert gcdata.inst_root_stack_top.ptr == q
+        gcdata.inst_root_stack_top = llmemory.cast_ptr_to_adr(p)
         del self._inside_roots_frame
+        #
+        array = p._obj._parentstructure()
+        index = p._obj._parent_index
+        for i in range(index, index + numcolors):
+            array.setitem(i, lltype._uninitialized(llmemory.Address))
 
     def op_gc_save_root(self, num, value):
-        assert 0 <= num < self._inside_roots_frame
+        """Save one value (int or ptr) into the frame."""
+        (p, q, numcolors, gcdata) = self._inside_roots_frame
+        assert 0 <= num < numcolors
+        if isinstance(value, int):
+            assert value & 1    # must be odd
+            v = llmemory.cast_int_to_adr(value)
+        else:
+            v = llmemory.cast_ptr_to_adr(value)
+        llmemory.cast_ptr_to_adr(p).address[num] = v
 
-    def op_gc_restore_root(self, num, value):
-        assert 0 <= num < self._inside_roots_frame
+    def op_gc_restore_root(self, c_num, v_value):
+        """Restore one value from the frame."""
+        num = c_num.value
+        (p, q, numcolors, gcdata) = self._inside_roots_frame
+        assert 0 <= num < numcolors
+        assert isinstance(v_value.concretetype, lltype.Ptr)
+        assert v_value.concretetype.TO._gckind == 'gc'
+        newvalue = llmemory.cast_ptr_to_adr(p).address[num]
+        newvalue = llmemory.cast_adr_to_ptr(newvalue, v_value.concretetype)
+        self.setvar(v_value, newvalue)
+    op_gc_restore_root.specialform = True
 
     # ____________________________________________________________
     # Overflow-detecting variants
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to