1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
diff -bur LuaJIT-2.1.0-beta3-orig/src/lj_str.c LuaJIT-2.1.0-beta3/src/lj_str.c
--- LuaJIT-2.1.0-beta3-orig/src/lj_str.c 2017-05-01 21:05:00.000000000 +0200
+++ LuaJIT-2.1.0-beta3/src/lj_str.c 2017-06-19 18:20:09.668443066 +0200
@@ -118,6 +118,16 @@
g->strhash = newhash;
}
+/*
+** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
+** compute its hash
+*/
+#if !defined(LUAI_HASHLIMIT)
+#define LUAI_HASHLIMIT 5
+#endif
+
+#define cast(t, exp) ((t)(exp))
+int luajittex_choose_hash_function = 0 ;
/* Intern a string and return string object. */
GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
{
@@ -126,9 +136,22 @@
GCobj *o;
MSize len = (MSize)lenx;
MSize a, b, h = len;
+ size_t step ;
+ size_t l1 ;
if (lenx >= LJ_MAX_STR)
lj_err_msg(L, LJ_ERR_STROV);
g = G(L);
+
+ if (len==0)
+ return &g->strempty;
+ if (luajittex_choose_hash_function==0) {
+ /* Lua 5.1.5 hash function */
+ /* for 5.2 max methods we also need to patch the vm eq */
+ step = (len>>LUAI_HASHLIMIT)+1; /* if string is too long, don't hash all its chars */
+ for (l1=len; l1>=step; l1-=step) /* compute hash */
+ h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
+ } else {
+ /* LuaJIT 2.0.2 hash function */
/* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
if (len >= 4) { /* Caveat: unaligned access! */
a = lj_getu32(str);
@@ -142,11 +165,15 @@
b = *(const uint8_t *)(str+(len>>1));
h ^= b; h -= lj_rol(b, 14);
} else {
+ /* Already done, kept for reference */
return &g->strempty;
}
a ^= h; a -= lj_rol(h, 11);
b ^= a; b -= lj_rol(a, 25);
h ^= b; h -= lj_rol(b, 16);
+ }
+
+
/* Check if the string has already been interned. */
o = gcref(g->strhash[h & g->strmask]);
if (LJ_LIKELY((((uintptr_t)str+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) {
|