[pypy-commit] pypy reverse-debugger: Fix: thread-local values are usually read directly (threadlocalref_get),

arigo pypy.commits at gmail.com
Mon Jul 4 06:07:18 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: reverse-debugger
Changeset: r85532:c2bd5822be84
Date: 2016-07-04 12:08 +0200
http://bitbucket.org/pypy/pypy/changeset/c2bd5822be84/

Log:	Fix: thread-local values are usually read directly
	(threadlocalref_get), but written with
	threadlocalref_addr()+op_raw_store(), which is not redone.

diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -324,8 +324,7 @@
         def get_or_make_raw():
             if we_are_translated():
                 _threadlocalref_seeme(self)
-                addr = llop.threadlocalref_addr(llmemory.Address)
-                return llop.raw_load(FIELDTYPE, addr, offset)
+                return llop.threadlocalref_load(FIELDTYPE, offset)
             else:
                 return getattr(self.local, 'rawvalue', zero)
 
@@ -333,8 +332,7 @@
         def setraw(value):
             if we_are_translated():
                 _threadlocalref_seeme(self)
-                addr = llop.threadlocalref_addr(llmemory.Address)
-                llop.raw_store(lltype.Void, addr, offset, value)
+                llop.threadlocalref_store(lltype.Void, offset, value)
             else:
                 self.local.rawvalue = value
 
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -981,6 +981,11 @@
         return self.op_raw_load(RESTYPE, _address_of_thread_local(), offset)
     op_threadlocalref_get.need_result_type = True
 
+    op_threadlocalref_load = op_threadlocalref_get
+
+    def op_threadlocalref_store(self, offset, value):
+        self.op_raw_store(_address_of_thread_local(), offset, value)
+
     def op_threadlocalref_acquire(self, prev):
         raise NotImplementedError
     def op_threadlocalref_release(self, prev):
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -542,6 +542,8 @@
 
     'threadlocalref_addr':  LLOp(),                   # get (or make) addr of tl
     'threadlocalref_get':   LLOp(sideeffects=False),  # read field (no check)
+    'threadlocalref_load':  LLOp(sideeffects=False),  # read field (with check)
+    'threadlocalref_store': LLOp(),                   # write field (with check)
     'threadlocalref_acquire':  LLOp(),                # lock for enum
     'threadlocalref_release':  LLOp(),                # lock for enum
     'threadlocalref_enum':  LLOp(sideeffects=False),  # enum all threadlocalrefs
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -963,8 +963,8 @@
             return None    # use the default
 
     def OP_THREADLOCALREF_GET(self, op):
-        typename = self.db.gettype(op.result.concretetype)
         if isinstance(op.args[0], Constant):
+            typename = self.db.gettype(op.result.concretetype)
             assert isinstance(op.args[0].value, CDefinedIntSymbolic)
             fieldname = op.args[0].value.expr
             assert fieldname.startswith('RPY_TLOFS_')
@@ -974,7 +974,19 @@
                 cdecl(typename, ''),
                 fieldname)
         else:
-            return 'OP_THREADLOCALREF_GET_NONCONST(%s, %s, %s);' % (
-                cdecl(typename, ''),
-                self.expr(op.args[0]),
-                self.expr(op.result))
+            # this is used for the fall-back path in the JIT
+            return self.OP_THREADLOCALREF_LOAD(op)
+
+    def OP_THREADLOCALREF_LOAD(self, op):
+        typename = self.db.gettype(op.result.concretetype)
+        return 'OP_THREADLOCALREF_LOAD(%s, %s, %s);' % (
+            cdecl(typename, ''),
+            self.expr(op.args[0]),
+            self.expr(op.result))
+
+    def OP_THREADLOCALREF_STORE(self, op):
+        typename = self.db.gettype(op.args[1].concretetype)
+        return 'OP_THREADLOCALREF_STORE(%s, %s, %s);' % (
+            cdecl(typename, ''),
+            self.expr(op.args[0]),
+            self.expr(op.args[1]))
diff --git a/rpython/translator/c/src/threadlocal.h b/rpython/translator/c/src/threadlocal.h
--- a/rpython/translator/c/src/threadlocal.h
+++ b/rpython/translator/c/src/threadlocal.h
@@ -115,13 +115,19 @@
 RPY_EXTERN pthread_key_t pypy_threadlocal_key;
 
 
-/* only for the fall-back path in the JIT */
-#define OP_THREADLOCALREF_GET_NONCONST(RESTYPE, offset, r)      \
+#define OP_THREADLOCALREF_LOAD(RESTYPE, offset, r)              \
     do {                                                        \
         char *a;                                                \
         OP_THREADLOCALREF_ADDR(a);                              \
         r = *(RESTYPE *)(a + offset);                           \
     } while (0)
 
+#define OP_THREADLOCALREF_STORE(VALTYPE, offset, value)         \
+    do {                                                        \
+        char *a;                                                \
+        OP_THREADLOCALREF_ADDR(a);                              \
+        *(VALTYPE *)(a + offset) = value;                       \
+    } while (0)
+
 
 #endif /* _SRC_THREADLOCAL_H */


More information about the pypy-commit mailing list