[pypy-commit] pypy default: Merge

stian noreply at buildbot.pypy.org
Sat May 2 02:38:17 CEST 2015


Author: stian
Branch: 
Changeset: r76973:df47fcbdecf4
Date: 2015-05-02 02:38 +0200
http://bitbucket.org/pypy/pypy/changeset/df47fcbdecf4/

Log:	Merge

diff --git a/rpython/jit/backend/llsupport/llerrno.py b/rpython/jit/backend/llsupport/llerrno.py
--- a/rpython/jit/backend/llsupport/llerrno.py
+++ b/rpython/jit/backend/llsupport/llerrno.py
@@ -40,6 +40,13 @@
     assert nerrno >= 0
     cpu._debug_errno_container[5] = nerrno
 
+def get_debug_saved_altlasterror(cpu):
+    return cpu._debug_errno_container[6]
+
+def set_debug_saved_altlasterror(cpu, nerrno):
+    assert nerrno >= 0
+    cpu._debug_errno_container[6] = nerrno
+
 def get_rpy_lasterror_offset(cpu):
     if cpu.translate_support_code:
         from rpython.rlib import rthread
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -3106,15 +3106,22 @@
             self.cpu.compile_loop(inputargs, ops, looptoken)
             #
             llerrno.set_debug_saved_lasterror(self.cpu, 24)
+            llerrno.set_debug_saved_altlasterror(self.cpu, 25)
             deadframe = self.cpu.execute_token(looptoken, 9, 8, 7, 6, 5, 4, 3)
             original_result = self.cpu.get_int_value(deadframe, 0)
             result = llerrno.get_debug_saved_lasterror(self.cpu)
-            print 'saveerr =', saveerr, ': got result =', result
+            altresult = llerrno.get_debug_saved_altlasterror(self.cpu)
+            print 'saveerr =', saveerr, ': got result =', result,
+            print 'and altresult =', altresult
             #
-            if saveerr == rffi.RFFI_SAVE_LASTERROR:
-                assert result == 42      # from the C code
+            if saveerr & rffi.RFFI_SAVE_LASTERROR:
+                # one from the C code, the other not touched
+                if saveerr & rffi.RFFI_ALT_ERRNO:
+                    assert (result, altresult) == (24, 42)
+                else:
+                    assert (result, altresult) == (42, 25)
             else:
-                assert result == 24      # not touched
+                assert (result, altresult) == (24, 25)      # not touched
             assert original_result == 3456789
 
     def test_call_release_gil_readsaved_lasterror(self):
@@ -3169,11 +3176,17 @@
             self.cpu.compile_loop(inputargs, ops, looptoken)
             #
             llerrno.set_debug_saved_lasterror(self.cpu, 24)
+            llerrno.set_debug_saved_altlasterror(self.cpu, 25)
             deadframe = self.cpu.execute_token(looptoken, 9, 8, 7, 6, 5, 4, 3)
             result = self.cpu.get_int_value(deadframe, 0)
             assert llerrno.get_debug_saved_lasterror(self.cpu) == 24
+            assert llerrno.get_debug_saved_altlasterror(self.cpu) == 25
             #
-            assert result == 24 + 345678900
+            if saveerr & rffi.RFFI_ALT_ERRNO:
+                expected_lasterror = 25
+            else:
+                expected_lasterror = 24
+            assert result == expected_lasterror + 345678900
 
     def test_call_release_gil_err_all(self):
         from rpython.translator.tool.cbuild import ExternalCompilationInfo
@@ -3228,7 +3241,6 @@
         for saveerr in [rffi.RFFI_ERR_ALL,
                         rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO, 
                        ]:
-            use_alt_errno = saveerr & rffi.RFFI_ALT_ERRNO
             faildescr = BasicFailDescr(1)
             inputargs = [BoxInt() for i in range(7)]
             i1 = BoxInt()
@@ -3244,7 +3256,7 @@
             looptoken = JitCellToken()
             self.cpu.compile_loop(inputargs, ops, looptoken)
             #
-            if use_alt_errno:
+            if saveerr & rffi.RFFI_ALT_ERRNO:
                 llerrno.set_debug_saved_alterrno(self.cpu, 8)
             else:
                 llerrno.set_debug_saved_errno(self.cpu, 8)
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
@@ -221,6 +221,7 @@
             mc.CALL(imm(follow_jump(SetLastError_addr)))
             # restore the stack position without assuming a particular
             # calling convention of _SetLastError()
+            self.mc.stack_frame_size_delta(-WORD)
             self.mc.MOV(esp, self.saved_stack_position_reg)
 
         if save_err & rffi.RFFI_READSAVED_ERRNO:
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -34,6 +34,26 @@
     side effect, but those side effects are idempotent (ie caching).
     If a particular call to this function ends up raising an exception, then it
     is handled like a normal function call (this decorator is ignored).
+
+    Note also that this optimisation will only take effect if the arguments
+    to the function are proven constant. By this we mean each argument
+    is either:
+
+      1) a constant from the RPython source code (e.g. "x = 2")
+      2) easily shown to be constant by the tracer
+      3) a promoted variable (see @jit.promote)
+
+    Examples of condition 2:
+
+      * i1 = int_eq(i0, 0), guard_true(i1)
+      * i1 = getfield_pc_pure(<constant>, "immutable_field")
+
+    In both cases, the tracer will deduce that i1 is constant.
+
+    Failing the above conditions, the function is not traced into (as if the
+    function were decorated with @jit.dont_look_inside). Generally speaking,
+    it is a bad idea to liberally sprinkle @jit.elidable without a concrete
+    need.
     """
     if DEBUG_ELIDABLE_FUNCTIONS:
         cache = {}
@@ -78,6 +98,29 @@
 
 @specialize.argtype(0)
 def promote(x):
+    """
+    Promotes a variable in a trace to a constant.
+
+    When a variable is promoted, a guard is inserted that assumes the value
+    of the variable is constant. In other words, the value of the variable
+    is checked to be the same as it was at trace collection time.  Once the
+    variable is assumed constant, more aggressive constant folding may be
+    possible.
+
+    If however, the guard fails frequently, a bridge will be generated
+    this time assuming the constancy of the variable under its new value.
+    This optimisation should be used carefully, as in extreme cases, where
+    the promoted variable is not very constant at all, code explosion can
+    occur. In turn this leads to poor performance.
+
+    Overpromotion is characterised by a cascade of bridges branching from
+    very similar guard_value opcodes, each guarding the same variable under
+    a different value.
+
+    Note that promoting a string with @jit.promote will promote by pointer.
+    To promote a string by value, see @jit.promote_string.
+
+    """
     return hint(x, promote=True)
 
 def promote_string(x):


More information about the pypy-commit mailing list