-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHeaders.hpp
More file actions
168 lines (142 loc) · 5.03 KB
/
Headers.hpp
File metadata and controls
168 lines (142 loc) · 5.03 KB
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//Hey! Don't go anywhere! This file actually requires global updating
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)//This updates often, it's called R_LUA_TNUMBER
#define check_exp(c,e) (e)//No need for update
#define ttype(o) ((o)->tt)//No need for update
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
#define tonumber(o,n) (ttype(o) == 3 || \//This updates often, it's called R_LUA_TNUMBER
(((o) = luaV_tonumber(o,n)) != 0))
//No need to update anything here, it's just headers from Lua source
struct r_GCheader
{
BYTE tt;
BYTE marked;
BYTE _pad;
};
union r_GCObject
{
r_GCheader gch;
std::uintptr_t ts; /* tstring */
std::uintptr_t u; /* userdata */
std::uintptr_t cl; /* closure */
std::uintptr_t h; /* table */
std::uintptr_t p; /* pointer */
std::uintptr_t uv; /* upvalue */
std::uintptr_t th; /* thread */
};
typedef union
{
r_GCObject* gc;
void* p;
std::double_t n;
int b;
} r_Value;
typedef struct r_lua_TValue
{
r_Value value;
r_lua_TValue* ptr;
int tt;
} r_TValue;
typedef r_TValue* r_StkId;
#define LUAI_GCGOAL 200 /* 200% (allow heap to double compared to live heap size) */
#define LUAI_GCSTEPMUL 200 /* GC runs 'twice the speed' of memory allocation */
#define LUAI_GCSTEPSIZE 1 /* GC runs every KB of memory allocation */
/*
** Possible states of the Garbage Collector
*/
#define GCSpause 0
#define GCSpropagate 1
#define GCSpropagateagain 2
#define GCSatomic 3
#define GCSsweep 4
/*
** macro to tell when main invariant (white objects cannot point to black
** ones) must be kept. During a collection, the sweep
** phase may break the invariant, as objects turned white may point to
** still-black objects. The invariant is restored when sweep ends and
** all objects are white again.
*/
#define keepinvariant(g) ((g)->gcstate == GCSpropagate || (g)->gcstate == GCSpropagateagain || (g)->gcstate == GCSatomic)
/*
** some useful bit tricks
*/
#define resetbits(x, m) ((x) &= cast_to(uint8_t, ~(m)))
#define setbits(x, m) ((x) |= (m))
#define testbits(x, m) ((x) & (m))
#define bitmask(b) (1 << (b))
#define bit2mask(b1, b2) (bitmask(b1) | bitmask(b2))
#define l_setbit(x, b) setbits(x, bitmask(b))
#define resetbit(x, b) resetbits(x, bitmask(b))
#define testbit(x, b) testbits(x, bitmask(b))
#define set2bits(x, b1, b2) setbits(x, (bit2mask(b1, b2)))
#define reset2bits(x, b1, b2) resetbits(x, (bit2mask(b1, b2)))
#define test2bits(x, b1, b2) testbits(x, (bit2mask(b1, b2)))
/*
** Layout for bit use in `marked' field:
** bit 0 - object is white (type 0)
** bit 1 - object is white (type 1)
** bit 2 - object is black
** bit 3 - object is fixed (should not be collected)
*/
#define WHITE0BIT 0
#define WHITE1BIT 1
#define BLACKBIT 2
#define FIXEDBIT 3
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
#define isgray(x) (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
#define isfixed(x) testbit((x)->gch.marked, FIXEDBIT)
#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
#define isdead(g, v) (((v)->gch.marked & (WHITEBITS | bitmask(FIXEDBIT))) == (otherwhite(g) & WHITEBITS))
#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
#define luaC_white(g) cast_to(uint8_t, ((g)->currentwhite) & WHITEBITS)
// Thread stack states
#define THREAD_ACTIVEBIT 0 // thread is currently active
#define THREAD_SLEEPINGBIT 1 // thread is not executing and stack should not be modified
#define luaC_threadactive(L) (testbit((L)->stackstate, THREAD_ACTIVEBIT))
#define luaC_threadsleeping(L) (testbit((L)->stackstate, THREAD_SLEEPINGBIT))
#define luaC_checkGC(L) \
{ \
condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK)); \
if (L->global->totalbytes >= L->global->GCthreshold) \
{ \
condhardmemtests(luaC_validate(L), 1); \
luaC_step(L, true); \
} \
else \
{ \
condhardmemtests(luaC_validate(L), 2); \
} \
}
#define luaC_barrier(L, p, v) \
{ \
if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \
luaC_barrierf(L, obj2gco(p), gcvalue(v)); \
}
#define luaC_barriert(L, t, v) \
{ \
if (iscollectable(v) && isblack(obj2gco(t)) && iswhite(gcvalue(v))) \
luaC_barriertable(L, t, gcvalue(v)); \
}
#define luaC_barrierfast(L, t) \
{ \
if (isblack(obj2gco(t))) \
luaC_barrierback(L, t); \
}
#define luaC_objbarrier(L, p, o) \
{ \
if (isblack(obj2gco(p)) && iswhite(obj2gco(o))) \
luaC_barrierf(L, obj2gco(p), obj2gco(o)); \
}
#define luaC_upvalbarrier(L, uv, tv) \
{ \
if (iscollectable(tv) && iswhite(gcvalue(tv)) && (!(uv) || (uv)->v != &(uv)->u.value)) \
luaC_barrierupval(L, gcvalue(tv)); \
}
#define luaC_checkthreadsleep(L) \
{ \
if (luaC_threadsleeping(L)) \
luaC_wakethread(L); \
}
#define luaC_init(L, o, tt) luaC_initobj(L, cast_to(GCObject*, (o)), tt)