Author: Armin Rigo <[email protected]>
Branch: fast-gil
Changeset: r72185:eaa2cbefc0e6
Date: 2014-06-24 12:03 +0200
http://bitbucket.org/pypy/pypy/changeset/eaa2cbefc0e6/

Log:    in-progress

diff --git a/rpython/jit/backend/llsupport/assembler.py 
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -307,11 +307,21 @@
     @staticmethod
     @rgc.no_collect
     def _reacquire_gil_asmgcc(css, old_rpy_fastgil):
-        # Only called if rpy_fastgil was reset to a different value
-        # by another thread or by a callback.  See description in
-        # transator/c/src/thread_pthread.c.
-        if not old_rpy_fastgil:
-            # first reacquire the GIL
+        # Before doing an external call, 'rpy_fastgil' is initialized to
+        # be equal to css.  This function is called if we find out after
+        # the call that it is no longer equal to css.  See description
+        # in transator/c/src/thread_pthread.c.
+
+        if old_rpy_fastgil == 0:
+            # this case occurs if some other thread stole the GIL but
+            # released it again.  What occurred here is that we changed
+            # 'rpy_fastgil' from 0 to 1, thus successfully requiring the
+            # GIL.
+            pass
+
+        elif old_rpy_fastgil == 1:
+            # 'rpy_fastgil' was (and still is) locked by someone else.
+            # We need to wait for the regular mutex.
             after = rffi.aroundstate.after
             if after:
                 after()
@@ -326,6 +336,7 @@
             oth.prev = asmgcroot.gcrootanchor
             asmgcroot.gcrootanchor.next = oth
             next.prev = oth
+
         # similar to trackgcroot.py:pypy_asm_stackwalk, second part:
         # detach the 'css' from the chained list
         from rpython.memory.gctransform import asmgcroot
@@ -339,14 +350,15 @@
     @rgc.no_collect
     def _reacquire_gil_shadowstack():
         # Simplified version of _reacquire_gil_asmgcc(): in shadowstack mode,
-        # rpy_fastgil contains only 0 or 1, and this must only be called when
-        # the old value stored in rpy_fastgil was 0.
+        # 'rpy_fastgil' contains only zero or non-zero, and this is only
+        # called when the old value stored in 'rpy_fastgil' was non-zero
+        # (i.e. still locked, must wait with the regular mutex)
         after = rffi.aroundstate.after
         if after:
             after()
 
     _REACQGIL0_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
-    _REACQGIL2_FUNC = lltype.Ptr(lltype.FuncType([rffi.CCHARP, rffi.CCHARP],
+    _REACQGIL2_FUNC = lltype.Ptr(lltype.FuncType([rffi.CCHARP, lltype.Signed],
                                                  lltype.Void))
 
     def _build_release_gil(self, gcrootmap):
diff --git a/rpython/jit/backend/x86/callbuilder.py 
b/rpython/jit/backend/x86/callbuilder.py
--- a/rpython/jit/backend/x86/callbuilder.py
+++ b/rpython/jit/backend/x86/callbuilder.py
@@ -98,9 +98,10 @@
         from rpython.jit.backend.x86.assembler import heap
         #
         if not self.asm._is_asmgcc():
-            # the helper takes no argument
+            # shadowstack: change 'rpy_fastgil' to 0 (it should be
+            # non-zero right now).
             self.change_extra_stack_depth = False
-            css_value = imm(1)
+            css_value = imm(0)
         else:
             from rpython.memory.gctransform import asmgcroot
             # build a 'css' structure on the stack: 2 words for the linkage,
@@ -134,14 +135,14 @@
         from rpython.jit.backend.x86.assembler import heap
         from rpython.jit.backend.x86 import rx86
         #
-        # check if we need to call the reopenstack() function
+        # check if we need to call the reacqgil() function or not
         # (to acquiring the GIL, remove the asmgcc head from
         # the chained list, etc.)
         mc = self.mc
         restore_edx = False
         if not self.asm._is_asmgcc():
             css = 0
-            css_value = imm(1)
+            css_value = imm(0)
             old_value = ecx
         else:
             from rpython.memory.gctransform import asmgcroot
@@ -158,7 +159,7 @@
                 old_value = esi
             mc.LEA_rs(css_value.value, css)
         #
-        mc.XOR_rr(old_value.value, old_value.value)
+        mc.MOV(old_value, imm(1))
         if rx86.fits_in_32bits(fastgil):
             mc.XCHG_rj(old_value.value, fastgil)
         else:
@@ -168,15 +169,15 @@
         mc.J_il8(rx86.Conditions['E'], 0)
         je_location = mc.get_relative_pos()
         #
-        # Yes, we need to call the reopenstack() function
-        self.save_result_value_reacq(restore_edx)
+        # Yes, we need to call the reacqgil() function
+        self.save_result_value_reacq()
         if self.asm._is_asmgcc():
             if IS_X86_32:
                 mc.MOV_sr(4, old_value.value)
                 mc.MOV_sr(0, css_value.value)
             # on X86_64, they are already in the right registers
         mc.CALL(imm(self.asm.reacqgil_addr))
-        self.restore_result_value_reacq(restore_edx)
+        self.restore_result_value_reacq()
         #
         # patch the JE above
         offset = mc.get_relative_pos() - je_location
@@ -198,11 +199,11 @@
         #else:
         #   for shadowstack, done for us by _reload_frame_if_necessary()
 
-    def save_result_value_reacq(self, restore_edx):
+    def save_result_value_reacq(self):
         """Overridden in CallBuilder32 and CallBuilder64"""
         raise NotImplementedError
 
-    def restore_result_value_reacq(self, restore_edx):
+    def restore_result_value_reacq(self):
         """Overridden in CallBuilder32 and CallBuilder64"""
         raise NotImplementedError
 
@@ -273,7 +274,7 @@
         else:
             CallBuilderX86.load_result(self)
 
-    def save_result_value_reacq(self, restore_edx):
+    def save_result_value_reacq(self):
         # Temporarily save the result value into [ESP+8].  We use "+8"
         # in order to leave the two initial words free, in case it's needed.
         # Also note that in this 32-bit case, a long long return value is
@@ -285,8 +286,7 @@
             # a float or a long long return
             if self.restype == 'L':
                 self.mc.MOV_sr(8, eax.value)      # long long
-                if not restore_edx:
-                    self.mc.MOV_sr(12, edx.value)
+                #self.mc.MOV_sr(12, edx.value) -- already done by the caller
             else:
                 self.mc.FSTPL_s(8)                # float return
         else:
@@ -297,7 +297,7 @@
                 assert self.ressize <= WORD
                 self.mc.MOV_sr(8, eax.value)
 
-    def restore_result_value_reacq(self, restore_edx):
+    def restore_result_value_reacq(self):
         # Opposite of save_result_value_reacq()
         if self.ressize == 0:      # void return
             return
@@ -305,8 +305,7 @@
             # a float or a long long return
             if self.restype == 'L':
                 self.mc.MOV_rs(eax.value, 8)      # long long
-                if not restore_edx:
-                    self.mc.MOV_rs(edx.value, 12)
+                #self.mc.MOV_rs(edx.value, 12) -- will be done by the caller
             else:
                 self.mc.FLDL_s(8)                 # float return
         else:
@@ -430,7 +429,7 @@
         else:
             CallBuilderX86.load_result(self)
 
-    def save_result_value_reacq(self, restore_edx):
+    def save_result_value_reacq(self):
         # Temporarily save the result value into [ESP].
         if self.ressize == 0:      # void return
             return
@@ -448,7 +447,7 @@
             assert self.restype == INT
             self.mc.MOV_sr(0, eax.value)
 
-    def restore_result_value_reacq(self, restore_edx):
+    def restore_result_value_reacq(self):
         # Opposite of save_result_value_reacq()
         if self.ressize == 0:      # void return
             return
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to