[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