aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-04-19 16:09:07 +0200
committerMike Pall <mike>2011-04-19 16:09:07 +0200
commitb3d10cdf62ce07e5662a73ec654dc3ce5c117966 (patch)
treecd804cc5ec888d7c9a65de20b0c569a65146e0b8 /src
parent4fbacaf887d9b891f385eea835d2a18fdb752ac2 (diff)
downloadluajit-b3d10cdf62ce07e5662a73ec654dc3ce5c117966.tar.gz
luajit-b3d10cdf62ce07e5662a73ec654dc3ce5c117966.tar.bz2
luajit-b3d10cdf62ce07e5662a73ec654dc3ce5c117966.zip
ARM: Workaround for unaligned accesses.
Diffstat (limited to 'src')
-rw-r--r--src/lj_str.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/lj_str.c b/src/lj_str.c
index 9e9650a2..01bd68e2 100644
--- a/src/lj_str.c
+++ b/src/lj_str.c
@@ -43,6 +43,18 @@ int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b)
43 return (int32_t)(a->len - b->len); 43 return (int32_t)(a->len - b->len);
44} 44}
45 45
46typedef union
47#ifdef __GNUC__
48__attribute__((packed))
49#endif
50Unaligned32 { uint32_t u; uint8_t b[4]; } Unaligned32;
51
52/* Unaligned read of uint32_t. */
53static uint32_t LJ_AINLINE str_getu32(const void *p)
54{
55 return ((const Unaligned32 *)p)->u;
56}
57
46/* Fast string data comparison. Caveat: unaligned access to 1st string! */ 58/* Fast string data comparison. Caveat: unaligned access to 1st string! */
47static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len) 59static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
48{ 60{
@@ -50,7 +62,7 @@ static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
50 lua_assert(len > 0); 62 lua_assert(len > 0);
51 lua_assert((((uintptr_t)a + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4); 63 lua_assert((((uintptr_t)a + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4);
52 do { /* Note: innocuous access up to end of string + 3. */ 64 do { /* Note: innocuous access up to end of string + 3. */
53 uint32_t v = *(const uint32_t *)(a+i) ^ *(const uint32_t *)(b+i); 65 uint32_t v = str_getu32(a+i) ^ *(const uint32_t *)(b+i);
54 if (v) { 66 if (v) {
55 i -= len; 67 i -= len;
56#if LJ_LE 68#if LJ_LE
@@ -103,11 +115,11 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
103 g = G(L); 115 g = G(L);
104 /* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */ 116 /* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
105 if (len >= 4) { /* Caveat: unaligned access! */ 117 if (len >= 4) { /* Caveat: unaligned access! */
106 a = *(const uint32_t *)str; 118 a = str_getu32(str);
107 h ^= *(const uint32_t *)(str+len-4); 119 h ^= str_getu32(str+len-4);
108 b = *(const uint32_t *)(str+(len>>1)-2); 120 b = str_getu32(str+(len>>1)-2);
109 h ^= b; h -= lj_rol(b, 14); 121 h ^= b; h -= lj_rol(b, 14);
110 b += *(const uint32_t *)(str+(len>>2)-1); 122 b += str_getu32(str+(len>>2)-1);
111 } else if (len > 0) { 123 } else if (len > 0) {
112 a = *(const uint8_t *)str; 124 a = *(const uint8_t *)str;
113 h ^= *(const uint8_t *)(str+len-1); 125 h ^= *(const uint8_t *)(str+len-1);