[pypy-commit] pypy jit-get-errno: Speed up the reads and writes of 'errno'.
arigo
noreply at buildbot.pypy.org
Thu Jun 26 12:38:39 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: jit-get-errno
Changeset: r72241:c8b2c8ee757a
Date: 2014-06-26 12:35 +0200
http://bitbucket.org/pypy/pypy/changeset/c8b2c8ee757a/
Log: Speed up the reads and writes of 'errno'.
diff --git a/rpython/jit/backend/llsupport/test/ztranslation_test.py b/rpython/jit/backend/llsupport/test/ztranslation_test.py
--- a/rpython/jit/backend/llsupport/test/ztranslation_test.py
+++ b/rpython/jit/backend/llsupport/test/ztranslation_test.py
@@ -3,7 +3,7 @@
from rpython.rlib.jit import JitDriver, unroll_parameters, set_param
from rpython.rlib.jit import PARAMETERS, dont_look_inside
from rpython.rlib.jit import promote
-from rpython.rlib import jit_hooks
+from rpython.rlib import jit_hooks, rposix
from rpython.rlib.objectmodel import keepalive_until_here
from rpython.rlib.rthread import ThreadLocalReference
from rpython.jit.backend.detect_cpu import getcpuclass
@@ -24,6 +24,7 @@
# - full optimizer
# - floats neg and abs
# - threadlocalref_get
+ # - get_errno, set_errno
class Frame(object):
_virtualizable_ = ['i']
@@ -64,6 +65,8 @@
if k - abs(j): raise ValueError
if k - abs(-j): raise ValueError
if t.get().nine != 9: raise ValueError
+ rposix.set_errno(total)
+ if rposix.get_errno() != total: raise ValueError
return chr(total % 253)
#
from rpython.rtyper.lltypesystem import lltype, rffi
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -2325,12 +2325,38 @@
ed = effectinfo.extradescrs[0]
assert isinstance(ed, ThreadLocalRefDescr)
addr1 = rffi.cast(lltype.Signed, ed.get_tlref_addr())
+ # 'addr1' is the address is the current thread, but we assume that
+ # it is a thread-local at a constant offset from %fs/%gs.
addr0 = stmtlocal.threadlocal_base()
addr = addr1 - addr0
assert rx86.fits_in_32bits(addr)
mc = self.mc
- mc.writechar(stmtlocal.SEGMENT_TL) # prefix
- mc.MOV_rj(resloc.value, addr)
+ mc.writechar(stmtlocal.SEGMENT_TL) # prefix: %fs or %gs
+ mc.MOV_rj(resloc.value, addr) # memory read
+
+ def get_set_errno(self, op, loc, issue_a_write):
+ # this function is only called on Linux
+ from rpython.jit.backend.x86 import stmtlocal
+ addr = stmtlocal.get_errno_tl()
+ assert rx86.fits_in_32bits(addr)
+ mc = self.mc
+ mc.writechar(stmtlocal.SEGMENT_TL) # prefix: %fs or %gs
+ # !!important: the *next* instruction must be the one using 'addr'!!
+ if issue_a_write:
+ if isinstance(loc, RegLoc):
+ mc.MOV32_jr(addr, loc.value) # memory write from reg
+ else:
+ assert isinstance(loc, ImmedLoc)
+ newvalue = loc.value
+ newvalue = rffi.cast(rffi.INT, newvalue)
+ newvalue = rffi.cast(lltype.Signed, newvalue)
+ mc.MOV32_ji(addr, newvalue) # memory write immediate
+ else:
+ assert isinstance(loc, RegLoc)
+ if IS_X86_32:
+ mc.MOV_rj(loc.value, addr) # memory read
+ elif IS_X86_64:
+ mc.MOVSX32_rj(loc.value, addr) # memory read, sign-extend
genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST
diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -693,6 +693,7 @@
self.perform_math(op, [loc0], loc0)
TLREF_SUPPORT = sys.platform.startswith('linux')
+ ERRNO_SUPPORT = sys.platform.startswith('linux')
def _consider_threadlocalref_get(self, op):
if self.TLREF_SUPPORT:
@@ -701,6 +702,22 @@
else:
self._consider_call(op)
+ def _consider_get_errno(self, op):
+ if self.ERRNO_SUPPORT:
+ resloc = self.force_allocate_reg(op.result)
+ self.assembler.get_set_errno(op, resloc, issue_a_write=False)
+ else:
+ self._consider_call(op)
+
+ def _consider_set_errno(self, op):
+ if self.ERRNO_SUPPORT:
+ # op.getarg(0) is the function set_errno; op.getarg(1) is
+ # the new errno value
+ loc0 = self.rm.make_sure_var_in_reg(op.getarg(1))
+ self.assembler.get_set_errno(op, loc0, issue_a_write=True)
+ else:
+ self._consider_call(op)
+
def _call(self, op, arglocs, force_store=[], guard_not_forced_op=None):
# we need to save registers on the stack:
#
@@ -780,6 +797,10 @@
return self._consider_math_sqrt(op)
if oopspecindex == EffectInfo.OS_THREADLOCALREF_GET:
return self._consider_threadlocalref_get(op)
+ if oopspecindex == EffectInfo.OS_GET_ERRNO:
+ return self._consider_get_errno(op)
+ if oopspecindex == EffectInfo.OS_SET_ERRNO:
+ return self._consider_set_errno(op)
self._consider_call(op)
def consider_call_may_force(self, op, guard_op):
diff --git a/rpython/jit/backend/x86/stmtlocal.py b/rpython/jit/backend/x86/stmtlocal.py
--- a/rpython/jit/backend/x86/stmtlocal.py
+++ b/rpython/jit/backend/x86/stmtlocal.py
@@ -21,6 +21,10 @@
asm("%s" : "=r"(result));
return result;
}
+static long pypy__get_errno_tl(void)
+{
+ return ((long)&errno) - pypy__threadlocal_base();
+}
''' % _instruction])
@@ -30,3 +34,10 @@
compilation_info=eci,
_nowrapper=True,
) #transactionsafe=True)
+
+get_errno_tl = rffi.llexternal(
+ 'pypy__get_errno_tl',
+ [], lltype.Signed,
+ compilation_info=eci,
+ _nowrapper=True,
+ ) #transactionsafe=True)
More information about the pypy-commit
mailing list