[pypy-commit] pypy stm: Clean up the implementation of the reads and writes of less than one word.

arigo noreply at buildbot.pypy.org
Fri Jan 20 14:25:05 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r51519:fe658ba14686
Date: 2012-01-20 13:24 +0100
http://bitbucket.org/pypy/pypy/changeset/fe658ba14686/

Log:	Clean up the implementation of the reads and writes of less than one
	word.

diff --git a/pypy/translator/c/src/g_prerequisite.h b/pypy/translator/c/src/g_prerequisite.h
--- a/pypy/translator/c/src/g_prerequisite.h
+++ b/pypy/translator/c/src/g_prerequisite.h
@@ -19,7 +19,7 @@
 #include <stddef.h>
 
 
-#if 0 //def __GNUC__       /* other platforms too, probably */  XXX FIX ME
+#ifdef __GNUC__       /* other platforms too, probably */
 typedef _Bool bool_t;
 #else
 typedef unsigned char bool_t;
diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py
--- a/pypy/translator/stm/funcgen.py
+++ b/pypy/translator/stm/funcgen.py
@@ -27,6 +27,7 @@
         return '%s = (%s)%s((long*)&%s);' % (
             newvalue, cresulttypename, funcname, expr)
     else:
+        assert fieldsize in (1, 2, 4)
         if simple_struct:
             # assume that the object is aligned, and any possible misalignment
             # comes from the field offset, so that it can be resolved at
@@ -35,14 +36,20 @@
             structdef = funcgen.db.gettypedefnode(STRUCT)
             basename = funcgen.expr(op.args[0])
             fieldname = op.args[1].value
-            return '%s = STM_read_partial_word(%s, %s, offsetof(%s, %s));' % (
+            trailing = ''
+            if T == lltype.Bool:
+                trailing = ' & 1'    # needed in this case, otherwise casting
+                                     # a several-bytes value to bool_t would
+                                     # take into account all the several bytes
+            return '%s = (%s)(stm_fx_read_partial(%s, offsetof(%s, %s))%s);'% (
                 newvalue, cresulttypename, basename,
                 cdecl(funcgen.db.gettype(STRUCT), ''),
-                structdef.c_struct_field_name(fieldname))
+                structdef.c_struct_field_name(fieldname),
+                trailing)
         #
         else:
-            return '%s = stm_read_partial_word(sizeof(%s), &%s);' % (
-                newvalue, cresulttypename, expr)
+            return '%s = (%s)stm_read_partial_%d(&%s);' % (
+                newvalue, cresulttypename, fieldsize, expr)
 
 def _stm_generic_set(funcgen, op, targetexpr, T):
     basename = funcgen.expr(op.args[0])
@@ -69,10 +76,9 @@
         return '%s((long*)&%s, (%s)%s);' % (
             funcname, targetexpr, newtype, newvalue)
     else:
-        itemtypename = funcgen.db.gettype(T)
-        citemtypename = cdecl(itemtypename, '')
-        return ('stm_write_partial_word(sizeof(%s), &%s, %s);' % (
-            citemtypename, targetexpr, newvalue))
+        assert fieldsize in (1, 2, 4)
+        return ('stm_write_partial_%d(&%s, (unsigned long)%s);' % (
+            fieldsize, targetexpr, newvalue))
 
 
 def field_expr(funcgen, args):
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -701,25 +701,47 @@
 }
 
 // XXX little-endian only!
-unsigned long stm_read_partial_word(int fieldsize, void *addr)
-{
-  int misalignment = ((long)addr) & (sizeof(void*)-1);
-  long *p = (long*)(((char *)addr) - misalignment);
-  unsigned long word = stm_read_word(p);
-  return word >> (misalignment * 8);
+#define READ_PARTIAL_WORD(T, fieldsize, addr)           \
+  int misalignment = ((long)addr) & (sizeof(void*)-1);  \
+  long *p = (long*)(((char *)addr) - misalignment);     \
+  unsigned long word = stm_read_word(p);                \
+  assert(sizeof(T) == fieldsize);                       \
+  return (T)(word >> (misalignment * 8));
+
+unsigned char stm_read_partial_1(void *addr) {
+  READ_PARTIAL_WORD(unsigned char, 1, addr)
 }
+unsigned short stm_read_partial_2(void *addr) {
+  READ_PARTIAL_WORD(unsigned short, 2, addr)
+}
+#if PYPY_LONG_BIT == 64
+unsigned int stm_read_partial_4(void *addr) {
+  READ_PARTIAL_WORD(unsigned int, 4, addr)
+}
+#endif
 
 // XXX little-endian only!
-void stm_write_partial_word(int fieldsize, void *addr, unsigned long nval)
-{
-  int misalignment = ((long)addr) & (sizeof(void*)-1);
-  long *p = (long*)(((char *)addr) - misalignment);
-  long val = nval << (misalignment * 8);
-  long word = stm_read_word(p);
-  long mask = ((1L << (fieldsize * 8)) - 1) << (misalignment * 8);
-  val = (val & mask) | (word & ~mask);
+#define WRITE_PARTIAL_WORD(fieldsize, addr, nval)                       \
+  int misalignment = ((long)addr) & (sizeof(void*)-1);                  \
+  long *p = (long*)(((char *)addr) - misalignment);                     \
+  long val = ((long)nval) << (misalignment * 8);                        \
+  long word = stm_read_word(p);                                         \
+  long mask = ((1L << (fieldsize * 8)) - 1) << (misalignment * 8);      \
+  val = (val & mask) | (word & ~mask);                                  \
   stm_write_word(p, val);
+
+void stm_write_partial_1(void *addr, unsigned char nval) {
+  WRITE_PARTIAL_WORD(1, addr, nval)
 }
+void stm_write_partial_2(void *addr, unsigned short nval) {
+  WRITE_PARTIAL_WORD(2, addr, nval)
+}
+#if PYPY_LONG_BIT == 64
+void stm_write_partial_4(void *addr, unsigned int nval) {
+  WRITE_PARTIAL_WORD(4, addr, nval)
+}
+#endif
+
 
 #if PYPY_LONG_BIT == 32
 long long stm_read_doubleword(long *addr)
@@ -791,7 +813,7 @@
 #if PYPY_LONG_BIT == 32
   stm_write_word(addr, ii);         /* 32 bits */
 #else
-  stm_write_partial_word(4, addr, ii);   /* 64 bits */
+  stm_write_partial_4(addr, ii);    /* 64 bits */
 #endif
 }
 
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -33,13 +33,21 @@
                                      2: in an inevitable transaction */
 
 // XXX little-endian only!
-#define STM_read_partial_word(T, base, offset)                          \
-    (T)(stm_read_word(                                                  \
+/* this macro is used if 'base' is a word-aligned pointer and 'offset'
+   is a compile-time constant */
+#define stm_fx_read_partial(base, offset)                               \
+       (stm_read_word(                                                  \
            (long*)(((char*)(base)) + ((offset) & ~(sizeof(void*)-1))))  \
         >> (8 * ((offset) & (sizeof(void*)-1))))
 
-unsigned long stm_read_partial_word(int fieldsize, void *addr);
-void stm_write_partial_word(int fieldsize, void *addr, unsigned long nval);
+unsigned char stm_read_partial_1(void *addr);
+unsigned short stm_read_partial_2(void *addr);
+void stm_write_partial_1(void *addr, unsigned char nval);
+void stm_write_partial_2(void *addr, unsigned short nval);
+#if PYPY_LONG_BIT == 64
+unsigned int stm_read_partial_4(void *addr);
+void stm_write_partial_4(void *addr, unsigned int nval);
+#endif
 
 double stm_read_double(long *addr);
 void stm_write_double(long *addr, double val);


More information about the pypy-commit mailing list