diff options
Diffstat (limited to 'src/lj_obj.h')
-rw-r--r-- | src/lj_obj.h | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/src/lj_obj.h b/src/lj_obj.h index 048a74f9..71146dfc 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
@@ -75,9 +75,37 @@ typedef struct GCRef { | |||
75 | ** a barrier has been omitted are annotated with a NOBARRIER comment. | 75 | ** a barrier has been omitted are annotated with a NOBARRIER comment. |
76 | ** | 76 | ** |
77 | ** The same logic applies for stores to table slots (array part or hash | 77 | ** The same logic applies for stores to table slots (array part or hash |
78 | ** part). ALL uses of lj_tab_set* require a barrier for the stored *value* | 78 | ** part). ALL uses of lj_tab_set* require a barrier for the stored value |
79 | ** (if it's a GC object). The barrier for the *key* is already handled | 79 | ** *and* the stored key, based on the above rules. In practice this means |
80 | ** internally by lj_tab_newkey. | 80 | ** a barrier is needed if *either* of the key or value are a GC object. |
81 | ** | ||
82 | ** It's ok to LEAVE OUT the write barrier in the following special cases: | ||
83 | ** - The stored value is nil. The key doesn't matter because it's either | ||
84 | ** not resurrected or lj_tab_newkey() will take care of the key barrier. | ||
85 | ** - The key doesn't matter if the *previously* stored value is guaranteed | ||
86 | ** to be non-nil (because the key is kept alive in the table). | ||
87 | ** - The key doesn't matter if it's guaranteed not to be part of the table, | ||
88 | ** since lj_tab_newkey() takes care of the key barrier. This applies | ||
89 | ** trivially to new tables, but watch out for resurrected keys. Storing | ||
90 | ** a nil value leaves the key in the table! | ||
91 | ** | ||
92 | ** In case of doubt use lj_gc_anybarriert() as it's rather cheap. It's used | ||
93 | ** by the interpreter for all table stores. | ||
94 | ** | ||
95 | ** Note: In contrast to Lua's GC, LuaJIT's GC does *not* specially mark | ||
96 | ** dead keys in tables. The reference is left in, but it's guaranteed to | ||
97 | ** be never dereferenced as long as the value is nil. It's ok if the key is | ||
98 | ** freed or if any object subsequently gets the same address. | ||
99 | ** | ||
100 | ** Not destroying dead keys helps to keep key hash slots stable. This avoids | ||
101 | ** specialization back-off for HREFK when a value flips between nil and | ||
102 | ** non-nil and the GC gets in the way. It also allows safely hoisting | ||
103 | ** HREF/HREFK across GC steps. Dead keys are only removed if a table is | ||
104 | ** resized (i.e. by NEWREF) and xREF must not be CSEd across a resize. | ||
105 | ** | ||
106 | ** The trade-off is that a write barrier for tables must take the key into | ||
107 | ** account, too. Implicitly resurrecting the key by storing a non-nil value | ||
108 | ** may invalidate the incremental GC invariant. | ||
81 | */ | 109 | */ |
82 | 110 | ||
83 | /* -- Common type definitions --------------------------------------------- */ | 111 | /* -- Common type definitions --------------------------------------------- */ |
@@ -136,10 +164,7 @@ typedef const TValue cTValue; | |||
136 | 164 | ||
137 | /* More external and GCobj tags for internal objects. */ | 165 | /* More external and GCobj tags for internal objects. */ |
138 | #define LAST_TT LUA_TTHREAD | 166 | #define LAST_TT LUA_TTHREAD |
139 | |||
140 | #define LUA_TPROTO (LAST_TT+1) | 167 | #define LUA_TPROTO (LAST_TT+1) |
141 | #define LUA_TUPVAL (LAST_TT+2) | ||
142 | #define LUA_TDEADKEY (LAST_TT+3) | ||
143 | 168 | ||
144 | /* Internal object tags. | 169 | /* Internal object tags. |
145 | ** | 170 | ** |
@@ -170,7 +195,7 @@ typedef const TValue cTValue; | |||
170 | #define LJ_TTHREAD (-7) | 195 | #define LJ_TTHREAD (-7) |
171 | #define LJ_TPROTO (-8) | 196 | #define LJ_TPROTO (-8) |
172 | #define LJ_TFUNC (-9) | 197 | #define LJ_TFUNC (-9) |
173 | #define LJ_TDEADKEY (-10) | 198 | /* Unused (-10) */ |
174 | #define LJ_TTAB (-11) | 199 | #define LJ_TTAB (-11) |
175 | #define LJ_TUDATA (-12) | 200 | #define LJ_TUDATA (-12) |
176 | /* This is just the canonical number type used in some places. */ | 201 | /* This is just the canonical number type used in some places. */ |
@@ -689,7 +714,7 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n) | |||
689 | /* -- Miscellaneous object handling --------------------------------------- */ | 714 | /* -- Miscellaneous object handling --------------------------------------- */ |
690 | 715 | ||
691 | /* Names and maps for internal and external object tags. */ | 716 | /* Names and maps for internal and external object tags. */ |
692 | LJ_DATA const char *const lj_obj_typename[1+LUA_TUPVAL+1]; | 717 | LJ_DATA const char *const lj_obj_typename[1+LUA_TPROTO+1]; |
693 | LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1]; | 718 | LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1]; |
694 | 719 | ||
695 | #define typename(o) (lj_obj_itypename[itypemap(o)]) | 720 | #define typename(o) (lj_obj_itypename[itypemap(o)]) |