diff options
Diffstat (limited to 'src/lj_udata.c')
-rw-r--r-- | src/lj_udata.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/lj_udata.c b/src/lj_udata.c index 7dada848..ee4a145d 100644 --- a/src/lj_udata.c +++ b/src/lj_udata.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include "lj_obj.h" | 9 | #include "lj_obj.h" |
10 | #include "lj_gc.h" | 10 | #include "lj_gc.h" |
11 | #include "lj_err.h" | ||
11 | #include "lj_udata.h" | 12 | #include "lj_udata.h" |
12 | 13 | ||
13 | GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env) | 14 | GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env) |
@@ -32,3 +33,30 @@ void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud) | |||
32 | lj_mem_free(g, ud, sizeudata(ud)); | 33 | lj_mem_free(g, ud, sizeudata(ud)); |
33 | } | 34 | } |
34 | 35 | ||
36 | #if LJ_64 | ||
37 | void *lj_lightud_intern(lua_State *L, void *p) | ||
38 | { | ||
39 | global_State *g = G(L); | ||
40 | uint64_t u = (uint64_t)p; | ||
41 | uint32_t up = lightudup(u); | ||
42 | uint32_t *segmap = mref(g->gc.lightudseg, uint32_t); | ||
43 | MSize segnum = g->gc.lightudnum; | ||
44 | if (segmap) { | ||
45 | MSize seg; | ||
46 | for (seg = 0; seg <= segnum; seg++) | ||
47 | if (segmap[seg] == up) /* Fast path. */ | ||
48 | return (void *)(((uint64_t)seg << LJ_LIGHTUD_BITS_LO) | lightudlo(u)); | ||
49 | segnum++; | ||
50 | /* Leave last segment unused to avoid clash with ITERN key. */ | ||
51 | if (segnum >= (1 << LJ_LIGHTUD_BITS_SEG)-1) lj_err_msg(L, LJ_ERR_BADLU); | ||
52 | } | ||
53 | if (!((segnum-1) & segnum) && segnum != 1) { | ||
54 | lj_mem_reallocvec(L, segmap, segnum, segnum ? 2*segnum : 2u, uint32_t); | ||
55 | setmref(g->gc.lightudseg, segmap); | ||
56 | } | ||
57 | g->gc.lightudnum = segnum; | ||
58 | segmap[segnum] = up; | ||
59 | return (void *)(((uint64_t)segnum << LJ_LIGHTUD_BITS_LO) | lightudlo(u)); | ||
60 | } | ||
61 | #endif | ||
62 | |||