diff options
author | Mike Pall <mike> | 2010-07-21 23:55:05 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-07-21 23:55:05 +0200 |
commit | c5feda2d532495e64a468f0a1cf549e1760dbc6d (patch) | |
tree | e352a67c09341c4de1c43d3961749a9533c5c40e /src | |
parent | 420124372b7643410a1cdd6f80b9cc8aa6ec1302 (diff) | |
download | luajit-c5feda2d532495e64a468f0a1cf549e1760dbc6d.tar.gz luajit-c5feda2d532495e64a468f0a1cf549e1760dbc6d.tar.bz2 luajit-c5feda2d532495e64a468f0a1cf549e1760dbc6d.zip |
Speed up string compares in string interning.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj.supp | 10 | ||||
-rw-r--r-- | src/lj_str.c | 47 |
2 files changed, 51 insertions, 6 deletions
diff --git a/src/lj.supp b/src/lj.supp index 9a1379d7..f1126ad7 100644 --- a/src/lj.supp +++ b/src/lj.supp | |||
@@ -4,3 +4,13 @@ | |||
4 | Memcheck:Addr4 | 4 | Memcheck:Addr4 |
5 | fun:lj_str_cmp | 5 | fun:lj_str_cmp |
6 | } | 6 | } |
7 | { | ||
8 | Optimized string compare | ||
9 | Memcheck:Addr4 | ||
10 | fun:lj_str_new | ||
11 | } | ||
12 | { | ||
13 | Optimized string compare | ||
14 | Memcheck:Cond | ||
15 | fun:lj_str_new | ||
16 | } | ||
diff --git a/src/lj_str.c b/src/lj_str.c index 5ba55bdd..1f31c615 100644 --- a/src/lj_str.c +++ b/src/lj_str.c | |||
@@ -43,6 +43,27 @@ 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 | ||
46 | /* Fast string data comparison. Caveat: unaligned access to 1st string! */ | ||
47 | static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len) | ||
48 | { | ||
49 | MSize i = 0; | ||
50 | lua_assert(len > 0); | ||
51 | lua_assert((((uintptr_t)a + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4); | ||
52 | do { /* Note: innocuous access up to end of string + 3. */ | ||
53 | uint32_t v = *(const uint32_t *)(a+i) ^ *(const uint32_t *)(b+i); | ||
54 | if (v) { | ||
55 | i -= len; | ||
56 | #if LJ_ARCH_ENDIAN == LUAJIT_LE | ||
57 | return (int32_t)i >= -3 ? (v << (32+(i<<3))) : 1; | ||
58 | #else | ||
59 | return (int32_t)i >= -3 ? (v >> (32+(i<<3))) : 1; | ||
60 | #endif | ||
61 | } | ||
62 | i += 4; | ||
63 | } while (i < len); | ||
64 | return 0; | ||
65 | } | ||
66 | |||
46 | /* Resize the string hash table (grow and shrink). */ | 67 | /* Resize the string hash table (grow and shrink). */ |
47 | void lj_str_resize(lua_State *L, MSize newmask) | 68 | void lj_str_resize(lua_State *L, MSize newmask) |
48 | { | 69 | { |
@@ -99,12 +120,26 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx) | |||
99 | b ^= a; b -= lj_rol(a, 25); | 120 | b ^= a; b -= lj_rol(a, 25); |
100 | h ^= b; h -= lj_rol(b, 16); | 121 | h ^= b; h -= lj_rol(b, 16); |
101 | /* Check if the string has already been interned. */ | 122 | /* Check if the string has already been interned. */ |
102 | for (o = gcref(g->strhash[h & g->strmask]); o != NULL; o = gcnext(o)) { | 123 | o = gcref(g->strhash[h & g->strmask]); |
103 | GCstr *tso = gco2str(o); | 124 | if (LJ_LIKELY((((uintptr_t)str + len) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) { |
104 | if (tso->len == len && (memcmp(str, strdata(tso), len) == 0)) { | 125 | while (o != NULL) { |
105 | /* Resurrect if dead. Can only happen with fixstring() (keywords). */ | 126 | GCstr *sx = gco2str(o); |
106 | if (isdead(g, o)) flipwhite(o); | 127 | if (sx->len == len && str_fastcmp(str, strdata(sx), len) == 0) { |
107 | return tso; /* Return existing string. */ | 128 | /* Resurrect if dead. Can only happen with fixstring() (keywords). */ |
129 | if (isdead(g, o)) flipwhite(o); | ||
130 | return sx; /* Return existing string. */ | ||
131 | } | ||
132 | o = gcnext(o); | ||
133 | } | ||
134 | } else { /* Slow path: end of string is too close to a page boundary. */ | ||
135 | while (o != NULL) { | ||
136 | GCstr *sx = gco2str(o); | ||
137 | if (sx->len == len && memcmp(str, strdata(sx), len) == 0) { | ||
138 | /* Resurrect if dead. Can only happen with fixstring() (keywords). */ | ||
139 | if (isdead(g, o)) flipwhite(o); | ||
140 | return sx; /* Return existing string. */ | ||
141 | } | ||
142 | o = gcnext(o); | ||
108 | } | 143 | } |
109 | } | 144 | } |
110 | /* Nope, create a new string. */ | 145 | /* Nope, create a new string. */ |