[pypy-commit] pypy errno-again: Support threadlocalref_get in the JIT even if the result is not exactly

arigo noreply at buildbot.pypy.org
Thu Jan 15 16:57:19 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: errno-again
Changeset: r75355:e090b33dff6c
Date: 2015-01-15 16:57 +0100
http://bitbucket.org/pypy/pypy/changeset/e090b33dff6c/

Log:	Support threadlocalref_get in the JIT even if the result is not
	exactly one word (like an rffi.INT).

diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -627,6 +627,7 @@
 
     def _prepare_threadlocalref_get(self, op, fcond):
         ofs0 = imm(op.getarg(1).getint())
+        xxxxxxxxxxxxxxxx check the size and signedness of op.getdescr()
         res = self.force_allocate_reg(op.result)
         return [ofs0, res]
 
diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -225,7 +225,8 @@
         # as arguments, and it returns the (possibly reallocated) jitframe.
         # The backend can optimize OS_THREADLOCALREF_GET calls to return a
         # field of this threadlocal_addr, but only if 'translate_support_code':
-        # in untranslated tests, threadlocal_addr is a dummy NULL.
+        # in untranslated tests, threadlocal_addr is a dummy container
+        # for errno tests only.
         FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF, llmemory.Address],
                                              llmemory.GCREF))
 
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
@@ -5,7 +5,7 @@
 from rpython.rlib.jit import promote
 from rpython.rlib import jit_hooks, rposix
 from rpython.rlib.objectmodel import keepalive_until_here
-from rpython.rlib.rthread import ThreadLocalReference
+from rpython.rlib.rthread import ThreadLocalReference, ThreadLocalField
 from rpython.jit.backend.detect_cpu import getcpuclass
 from rpython.jit.backend.test.support import CCompiledMixin
 from rpython.jit.codewriter.policy import StopAtXPolicy
@@ -128,7 +128,8 @@
 
         class Foo(object):
             pass
-        t = ThreadLocalReference(Foo)
+        t = ThreadLocalReference(Foo, loop_invariant=True)
+        tf = ThreadLocalField(lltype.Char, "test_call_assembler_")
 
         def change(newthing):
             somewhere_else.frame.thing = newthing
@@ -156,6 +157,7 @@
                 frame.thing = Thing(nextval + 1)
                 i += 1
                 if t.get().nine != 9: raise ValueError
+                if ord(tf.getraw()) != 0x92: raise ValueError
             return frame.thing.val
 
         driver2 = JitDriver(greens = [], reds = ['n'])
@@ -181,6 +183,7 @@
             foo = Foo()
             foo.nine = value
             t.set(foo)
+            tf.setraw("\x92")
             return foo
 
         def mainall(codeno, bound):
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
@@ -2345,7 +2345,7 @@
         assert isinstance(reg, RegLoc)
         self.mc.MOV_rr(reg.value, ebp.value)
 
-    def threadlocalref_get(self, offset, resloc):
+    def threadlocalref_get(self, offset, resloc, size, sign):
         # This loads the stack location THREADLOCAL_OFS into a
         # register, and then read the word at the given offset.
         # It is only supported if 'translate_support_code' is
@@ -2355,7 +2355,8 @@
         assert self.cpu.translate_support_code
         assert isinstance(resloc, RegLoc)
         self.mc.MOV_rs(resloc.value, THREADLOCAL_OFS)
-        self.mc.MOV_rm(resloc.value, (resloc.value, offset))
+        self.load_from_mem(resloc, addr_add_const(resloc, offset),
+                           imm(size), imm(sign))
 
     def genop_discard_zero_array(self, op, arglocs):
         (base_loc, startindex_loc, bytes_loc,
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
@@ -702,8 +702,11 @@
     def _consider_threadlocalref_get(self, op):
         if self.translate_support_code:
             offset = op.getarg(1).getint()   # getarg(0) == 'threadlocalref_get'
+            calldescr = op.getdescr()
+            size = calldescr.get_result_size()
+            sign = calldescr.is_result_signed()
             resloc = self.force_allocate_reg(op.result)
-            self.assembler.threadlocalref_get(offset, resloc)
+            self.assembler.threadlocalref_get(offset, resloc, size, sign)
         else:
             self._consider_call(op)
 
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1993,10 +1993,6 @@
         return [op0, op1]
 
     def rewrite_op_threadlocalref_get(self, op):
-        # only supports RESTYPE being exactly one word.
-        RESTYPE = op.result.concretetype
-        assert (RESTYPE in (lltype.Signed, lltype.Unsigned, llmemory.Address)
-                or isinstance(RESTYPE, lltype.Ptr))
         c_offset, = op.args
         op1 = self.prepare_builtin_call(op, 'threadlocalref_get', [c_offset])
         if c_offset.value.loop_invariant:
diff --git a/rpython/jit/metainterp/test/test_threadlocal.py b/rpython/jit/metainterp/test/test_threadlocal.py
--- a/rpython/jit/metainterp/test/test_threadlocal.py
+++ b/rpython/jit/metainterp/test/test_threadlocal.py
@@ -17,6 +17,16 @@
         res = self.interp_operations(f, [])
         assert res == 0x544c
 
+    def test_threadlocalref_get_char(self):
+        tlfield = rthread.ThreadLocalField(lltype.Char, 'foobar_test_char_')
+
+        def f():
+            tlfield.setraw('\x92')
+            return ord(tlfield.getraw())
+
+        res = self.interp_operations(f, [])
+        assert res == 0x92
+
 
 class TestLLtype(ThreadLocalTest, LLJitMixin):
     pass


More information about the pypy-commit mailing list