Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/VM/src/lgc.h
2725 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details
3
#pragma once
4
5
#include "ldo.h"
6
#include "lobject.h"
7
#include "lstate.h"
8
9
/*
10
** Default settings for GC tunables (settable via lua_gc)
11
*/
12
#define LUAI_GCGOAL 200 // 200% (allow heap to double compared to live heap size)
13
#define LUAI_GCSTEPMUL 200 // GC runs 'twice the speed' of memory allocation
14
#define LUAI_GCSTEPSIZE 1 // GC runs every KB of memory allocation
15
16
/*
17
** Possible states of the Garbage Collector
18
*/
19
#define GCSpause 0
20
#define GCSpropagate 1
21
#define GCSpropagateagain 2
22
#define GCSatomic 3
23
#define GCSsweep 4
24
25
/*
26
** The main invariant of the garbage collector, while marking objects,
27
** is that a black object can never point to a white one. This invariant
28
** is not being enforced during a sweep phase, and is restored when sweep
29
** ends.
30
*/
31
#define keepinvariant(g) ((g)->gcstate == GCSpropagate || (g)->gcstate == GCSpropagateagain || (g)->gcstate == GCSatomic)
32
33
/*
34
** some useful bit tricks
35
*/
36
#define resetbits(x, m) ((x) &= cast_to(uint8_t, ~(m)))
37
#define setbits(x, m) ((x) |= (m))
38
#define testbits(x, m) ((x) & (m))
39
#define bitmask(b) (1 << (b))
40
#define bit2mask(b1, b2) (bitmask(b1) | bitmask(b2))
41
#define l_setbit(x, b) setbits(x, bitmask(b))
42
#define resetbit(x, b) resetbits(x, bitmask(b))
43
#define testbit(x, b) testbits(x, bitmask(b))
44
#define set2bits(x, b1, b2) setbits(x, (bit2mask(b1, b2)))
45
#define reset2bits(x, b1, b2) resetbits(x, (bit2mask(b1, b2)))
46
#define test2bits(x, b1, b2) testbits(x, (bit2mask(b1, b2)))
47
48
/*
49
** Layout for bit use in `marked' field:
50
** bit 0 - object is white (type 0)
51
** bit 1 - object is white (type 1)
52
** bit 2 - object is black
53
** bit 3 - object is fixed (should not be collected)
54
*/
55
56
#define WHITE0BIT 0
57
#define WHITE1BIT 1
58
#define BLACKBIT 2
59
#define FIXEDBIT 3
60
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
61
62
#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
63
#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
64
#define isgray(x) (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
65
#define isfixed(x) testbit((x)->gch.marked, FIXEDBIT)
66
67
#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
68
#define isdead(g, v) (((v)->gch.marked & (WHITEBITS | bitmask(FIXEDBIT))) == (otherwhite(g) & WHITEBITS))
69
70
#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
71
#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
72
73
#define luaC_white(g) cast_to(uint8_t, ((g)->currentwhite) & WHITEBITS)
74
75
#define luaC_needsGC(L) (L->global->totalbytes >= L->global->GCthreshold)
76
77
#define luaC_checkGC(L) \
78
{ \
79
condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK, 0)); \
80
if (luaC_needsGC(L)) \
81
{ \
82
condhardmemtests(luaC_validate(L), 1); \
83
luaC_step(L, true); \
84
} \
85
else \
86
{ \
87
condhardmemtests(luaC_validate(L), 2); \
88
} \
89
}
90
91
#define luaC_barrier(L, p, v) \
92
{ \
93
if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \
94
luaC_barrierf(L, obj2gco(p), gcvalue(v)); \
95
}
96
97
#define luaC_barriert(L, t, v) \
98
{ \
99
if (iscollectable(v) && isblack(obj2gco(t)) && iswhite(gcvalue(v))) \
100
luaC_barriertable(L, t, gcvalue(v)); \
101
}
102
103
#define luaC_barrierfast(L, t) \
104
{ \
105
if (isblack(obj2gco(t))) \
106
luaC_barrierback(L, obj2gco(t), &t->gclist); \
107
}
108
109
#define luaC_objbarrier(L, p, o) \
110
{ \
111
if (isblack(obj2gco(p)) && iswhite(obj2gco(o))) \
112
luaC_barrierf(L, obj2gco(p), obj2gco(o)); \
113
}
114
115
#define luaC_threadbarrier(L) \
116
{ \
117
if (isblack(obj2gco(L))) \
118
luaC_barrierback(L, obj2gco(L), &L->gclist); \
119
}
120
121
#define luaC_init(L, o, tt_) \
122
{ \
123
o->marked = luaC_white(L->global); \
124
o->tt = tt_; \
125
o->memcat = L->activememcat; \
126
}
127
128
LUAI_FUNC void luaC_freeall(lua_State* L);
129
LUAI_FUNC size_t luaC_step(lua_State* L, bool assist);
130
LUAI_FUNC void luaC_fullgc(lua_State* L);
131
LUAI_FUNC void luaC_initobj(lua_State* L, GCObject* o, uint8_t tt);
132
LUAI_FUNC void luaC_upvalclosed(lua_State* L, UpVal* uv);
133
LUAI_FUNC void luaC_barrierf(lua_State* L, GCObject* o, GCObject* v);
134
LUAI_FUNC void luaC_barriertable(lua_State* L, LuaTable* t, GCObject* v);
135
LUAI_FUNC void luaC_barrierback(lua_State* L, GCObject* o, GCObject** gclist);
136
LUAI_FUNC void luaC_validate(lua_State* L);
137
LUAI_FUNC void luaC_dump(lua_State* L, void* file, const char* (*categoryName)(lua_State* L, uint8_t memcat));
138
LUAI_FUNC void luaC_enumheap(
139
lua_State* L,
140
void* context,
141
void (*node)(void* context, void* ptr, uint8_t tt, uint8_t memcat, size_t size, const char* name),
142
void (*edge)(void* context, void* from, void* to, const char* name)
143
);
144
LUAI_FUNC int64_t luaC_allocationrate(lua_State* L);
145
LUAI_FUNC const char* luaC_statename(int state);
146
147