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): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit