Skip to content

Commit 8052ebc

Browse files
committed
Introduce generational GC
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent 21977ea commit 8052ebc

19 files changed

+1531
-794
lines changed

libs/jit/src/jit_aarch64.erl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,25 +163,25 @@
163163
| {maybe_free_aarch64_register(), '&', non_neg_integer(), '!=', integer()}
164164
| {{free, aarch64_register()}, '==', {free, aarch64_register()}}.
165165

166-
% ctx->e is 0x28
167-
% ctx->x is 0x30
166+
% ctx->e is 0x50
167+
% ctx->x is 0x58
168168
-define(WORD_SIZE, 8).
169169
-define(CTX_REG, r0).
170170
-define(JITSTATE_REG, r1).
171171
-define(NATIVE_INTERFACE_REG, r2).
172-
-define(Y_REGS, {?CTX_REG, 16#28}).
173-
-define(X_REG(N), {?CTX_REG, 16#30 + (N * ?WORD_SIZE)}).
174-
-define(CP, {?CTX_REG, 16#B8}).
175-
-define(FP_REGS, {?CTX_REG, 16#C0}).
172+
-define(Y_REGS, {?CTX_REG, 16#50}).
173+
-define(X_REG(N), {?CTX_REG, 16#58 + (N * ?WORD_SIZE)}).
174+
-define(CP, {?CTX_REG, 16#E0}).
175+
-define(FP_REGS, {?CTX_REG, 16#E8}).
176176
-define(FP_REG_OFFSET(State, F),
177177
(F *
178178
case (State)#state.variant band ?JIT_VARIANT_FLOAT32 of
179179
0 -> 8;
180180
_ -> 4
181181
end)
182182
).
183-
-define(BS, {?CTX_REG, 16#C8}).
184-
-define(BS_OFFSET, {?CTX_REG, 16#D0}).
183+
-define(BS, {?CTX_REG, 16#F0}).
184+
-define(BS_OFFSET, {?CTX_REG, 16#F8}).
185185
-define(JITSTATE_MODULE, {?JITSTATE_REG, 0}).
186186
-define(JITSTATE_CONTINUATION, {?JITSTATE_REG, 16#8}).
187187
-define(JITSTATE_REDUCTIONCOUNT, {?JITSTATE_REG, 16#10}).

libs/jit/src/jit_armv6m.erl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,15 +165,15 @@
165165
| {{free, armv6m_register()}, '==', {free, armv6m_register()}}.
166166

167167
% ctx->e is 0x28
168-
% ctx->x is 0x30
168+
% ctx->x is 0x2C
169169
-define(CTX_REG, r0).
170170
-define(NATIVE_INTERFACE_REG, r2).
171-
-define(Y_REGS, {?CTX_REG, 16#14}).
172-
-define(X_REG(N), {?CTX_REG, 16#18 + (N * 4)}).
173-
-define(CP, {?CTX_REG, 16#5C}).
174-
-define(FP_REGS, {?CTX_REG, 16#60}).
175-
-define(BS, {?CTX_REG, 16#64}).
176-
-define(BS_OFFSET, {?CTX_REG, 16#68}).
171+
-define(Y_REGS, {?CTX_REG, 16#28}).
172+
-define(X_REG(N), {?CTX_REG, 16#2C + (N * 4)}).
173+
-define(CP, {?CTX_REG, 16#70}).
174+
-define(FP_REGS, {?CTX_REG, 16#74}).
175+
-define(BS, {?CTX_REG, 16#78}).
176+
-define(BS_OFFSET, {?CTX_REG, 16#7C}).
177177
% JITSTATE is on stack, accessed via stack offset
178178
% These macros now expect a register that contains the jit_state pointer
179179
-define(JITSTATE_MODULE(Reg), {Reg, 0}).

libs/jit/src/jit_riscv32.erl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,16 +194,16 @@
194194
| {{free, riscv32_register()}, '==', {free, riscv32_register()}}.
195195

196196
% Context offsets (32-bit architecture)
197-
% ctx->e is 0x14
198-
% ctx->x is 0x18
197+
% ctx->e is 0x28
198+
% ctx->x is 0x2C
199199
-define(CTX_REG, a0).
200200
-define(NATIVE_INTERFACE_REG, a2).
201-
-define(Y_REGS, {?CTX_REG, 16#14}).
202-
-define(X_REG(N), {?CTX_REG, 16#18 + (N * 4)}).
203-
-define(CP, {?CTX_REG, 16#5C}).
204-
-define(FP_REGS, {?CTX_REG, 16#60}).
205-
-define(BS, {?CTX_REG, 16#64}).
206-
-define(BS_OFFSET, {?CTX_REG, 16#68}).
201+
-define(Y_REGS, {?CTX_REG, 16#28}).
202+
-define(X_REG(N), {?CTX_REG, 16#2C + (N * 4)}).
203+
-define(CP, {?CTX_REG, 16#70}).
204+
-define(FP_REGS, {?CTX_REG, 16#74}).
205+
-define(BS, {?CTX_REG, 16#78}).
206+
-define(BS_OFFSET, {?CTX_REG, 16#7C}).
207207
% JITSTATE is in a1 register (no prolog, following aarch64 model)
208208
-define(JITSTATE_REG, a1).
209209
% Return address register (like LR in AArch64)

libs/jit/src/jit_x86_64.erl

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,28 +149,28 @@
149149
-define(WORD_SIZE, 8).
150150

151151
% Following offsets are verified with static asserts in jit.c
152-
% ctx->e is 0x28
153-
% ctx->x is 0x30
154-
% ctx->cp is 0xB8
155-
% ctx->fr is 0xC0
156-
% ctx->bs is 0xC8
157-
% ctx->bs_offset is 0xD0
152+
% ctx->e is 0x50
153+
% ctx->x is 0x58
154+
% ctx->cp is 0xE0
155+
% ctx->fr is 0xE8
156+
% ctx->bs is 0xF0
157+
% ctx->bs_offset is 0xF8
158158
-define(CTX_REG, rdi).
159159
-define(JITSTATE_REG, rsi).
160160
-define(NATIVE_INTERFACE_REG, rdx).
161-
-define(Y_REGS, {16#28, ?CTX_REG}).
162-
-define(X_REG(N), {16#30 + (N * ?WORD_SIZE), ?CTX_REG}).
163-
-define(CP, {16#B8, ?CTX_REG}).
164-
-define(FP_REGS, {16#C0, ?CTX_REG}).
161+
-define(Y_REGS, {16#50, ?CTX_REG}).
162+
-define(X_REG(N), {16#58 + (N * ?WORD_SIZE), ?CTX_REG}).
163+
-define(CP, {16#E0, ?CTX_REG}).
164+
-define(FP_REGS, {16#E8, ?CTX_REG}).
165165
-define(FP_REG_OFFSET(State, F),
166166
(F *
167167
case (State)#state.variant band ?JIT_VARIANT_FLOAT32 of
168168
0 -> 8;
169169
_ -> 4
170170
end)
171171
).
172-
-define(BS, {16#C8, ?CTX_REG}).
173-
-define(BS_OFFSET, {16#D0, ?CTX_REG}).
172+
-define(BS, {16#F0, ?CTX_REG}).
173+
-define(BS_OFFSET, {16#F8, ?CTX_REG}).
174174
-define(JITSTATE_MODULE, {0, ?JITSTATE_REG}).
175175
-define(JITSTATE_CONTINUATION, {16#8, ?JITSTATE_REG}).
176176
-define(JITSTATE_REMAINING_REDUCTIONS, {16#10, ?JITSTATE_REG}).

src/libAtomVM/context.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ Context *context_new(GlobalContext *glb)
8181
ctx->min_heap_size = 0;
8282
ctx->max_heap_size = 0;
8383
ctx->heap_growth_strategy = BoundedFreeHeapGrowth;
84+
ctx->fullsweep_after = 65535;
85+
ctx->gc_count = 0;
8486
ctx->has_min_heap_size = 0;
8587
ctx->has_max_heap_size = 0;
8688

@@ -1209,6 +1211,14 @@ COLD_FUNC void context_dump(Context *ctx)
12091211
ct++;
12101212
}
12111213

1214+
fprintf(stderr, "\n\nHeap\n----\n");
1215+
fprintf(stderr, "young heap: %zu words\n", (size_t) (ctx->heap.heap_end - ctx->heap.heap_start));
1216+
if (ctx->heap.old_heap_start) {
1217+
fprintf(stderr, "old heap: %zu words (used: %zu)\n",
1218+
(size_t) (ctx->heap.old_heap_end - ctx->heap.old_heap_start),
1219+
(size_t) (ctx->heap.old_heap_ptr - ctx->heap.old_heap_start));
1220+
}
1221+
12121222
fprintf(stderr, "\n\nMailbox\n-------\n");
12131223
mailbox_crashdump(ctx);
12141224

src/libAtomVM/context.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ struct Context
113113
size_t min_heap_size;
114114
size_t max_heap_size;
115115
enum HeapGrowthStrategy heap_growth_strategy;
116+
unsigned int fullsweep_after;
117+
unsigned int gc_count;
116118

117119
// saved state when scheduled out
118120
Module *saved_module;

src/libAtomVM/defaultatoms.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ X(EMU_ATOM, "\x3", "emu")
206206
X(JIT_ATOM, "\x3", "jit")
207207
X(EMU_FLAVOR_ATOM, "\xA", "emu_flavor")
208208
X(CODE_SERVER_ATOM, "\xB", "code_server")
209+
X(FULLSWEEP_AFTER_ATOM, "\xF", "fullsweep_after")
209210
X(LOAD_ATOM, "\x4", "load")
210211
X(JIT_X86_64_ATOM, "\xA", "jit_x86_64")
211212
X(JIT_AARCH64_ATOM, "\xB", "jit_aarch64")

src/libAtomVM/erl_nif_priv.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ static inline void erl_nif_env_partial_init_from_globalcontext(ErlNifEnv *env, G
6363
env->heap.heap_start = NULL;
6464
env->heap.heap_ptr = NULL;
6565
env->heap.heap_end = NULL;
66+
env->heap.high_water_mark = NULL;
67+
env->heap.old_heap_start = NULL;
68+
env->heap.old_heap_ptr = NULL;
69+
env->heap.old_heap_end = NULL;
70+
env->heap.old_mso_list = term_nil();
6671
env->stack_pointer = NULL;
6772
env->x[0] = term_nil();
6873
env->x[1] = term_nil();
@@ -76,6 +81,11 @@ static inline void erl_nif_env_partial_init_from_resource(ErlNifEnv *env, void *
7681
env->heap.heap_start = NULL;
7782
env->heap.heap_ptr = NULL;
7883
env->heap.heap_end = NULL;
84+
env->heap.high_water_mark = NULL;
85+
env->heap.old_heap_start = NULL;
86+
env->heap.old_heap_ptr = NULL;
87+
env->heap.old_heap_end = NULL;
88+
env->heap.old_mso_list = term_nil();
7989
env->stack_pointer = NULL;
8090
env->x[0] = term_nil();
8191
env->x[1] = term_nil();

src/libAtomVM/jit.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,23 @@ _Static_assert(
6868

6969
// Verify offsets in jit_x86_64.erl
7070
#if JIT_ARCH_TARGET == JIT_ARCH_X86_64 || JIT_ARCH_TARGET == JIT_ARCH_AARCH64
71-
_Static_assert(offsetof(Context, e) == 0x28, "ctx->e is 0x28 in jit/src/jit_{aarch64,x86_64}.erl");
72-
_Static_assert(offsetof(Context, x) == 0x30, "ctx->x is 0x30 in jit/src/jit_{aarch64,x86_64}.erl");
73-
_Static_assert(offsetof(Context, cp) == 0xB8, "ctx->cp is 0xB8 in jit/src/jit_{aarch64,x86_64}.erl");
74-
_Static_assert(offsetof(Context, fr) == 0xC0, "ctx->fr is 0xC0 in jit/src/jit_{aarch64,x86_64}.erl");
75-
_Static_assert(offsetof(Context, bs) == 0xC8, "ctx->bs is 0xC8 in jit/src/jit_{aarch64,x86_64}.erl");
76-
_Static_assert(offsetof(Context, bs_offset) == 0xD0, "ctx->bs_offset is 0xD0 in jit/src/jit_{aarch64,x86_64}.erl");
71+
_Static_assert(offsetof(Context, e) == 0x50, "ctx->e is 0x50 in jit/src/jit_{aarch64,x86_64}.erl");
72+
_Static_assert(offsetof(Context, x) == 0x58, "ctx->x is 0x58 in jit/src/jit_{aarch64,x86_64}.erl");
73+
_Static_assert(offsetof(Context, cp) == 0xE0, "ctx->cp is 0xE0 in jit/src/jit_{aarch64,x86_64}.erl");
74+
_Static_assert(offsetof(Context, fr) == 0xE8, "ctx->fr is 0xE8 in jit/src/jit_{aarch64,x86_64}.erl");
75+
_Static_assert(offsetof(Context, bs) == 0xF0, "ctx->bs is 0xF0 in jit/src/jit_{aarch64,x86_64}.erl");
76+
_Static_assert(offsetof(Context, bs_offset) == 0xF8, "ctx->bs_offset is 0xF8 in jit/src/jit_{aarch64,x86_64}.erl");
7777

7878
_Static_assert(offsetof(JITState, module) == 0x0, "jit_state->module is 0x0 in jit/src/jit_{aarch64,x86_64}.erl");
7979
_Static_assert(offsetof(JITState, continuation) == 0x8, "jit_state->continuation is 0x8 in jit/src/jit_{aarch64,x86_64}.erl");
8080
_Static_assert(offsetof(JITState, remaining_reductions) == 0x10, "jit_state->remaining_reductions is 0x10 in jit/src/jit_{aarch64,x86_64}.erl");
8181
#elif JIT_ARCH_TARGET == JIT_ARCH_ARMV6M
82-
_Static_assert(offsetof(Context, e) == 0x14, "ctx->e is 0x14 in jit/src/jit_armv6m.erl");
83-
_Static_assert(offsetof(Context, x) == 0x18, "ctx->x is 0x18 in jit/src/jit_armv6m.erl");
84-
_Static_assert(offsetof(Context, cp) == 0x5C, "ctx->cp is 0x5C in jit/src/jit_armv6m.erl");
85-
_Static_assert(offsetof(Context, fr) == 0x60, "ctx->fr is 0x60 in jit/src/jit_armv6m.erl");
86-
_Static_assert(offsetof(Context, bs) == 0x64, "ctx->bs is 0x64 in jit/src/jit_armv6m.erl");
87-
_Static_assert(offsetof(Context, bs_offset) == 0x68, "ctx->bs_offset is 0x68 in jit/src/jit_armv6m.erl");
82+
_Static_assert(offsetof(Context, e) == 0x28, "ctx->e is 0x28 in jit/src/jit_armv6m.erl");
83+
_Static_assert(offsetof(Context, x) == 0x2C, "ctx->x is 0x2C in jit/src/jit_armv6m.erl");
84+
_Static_assert(offsetof(Context, cp) == 0x70, "ctx->cp is 0x70 in jit/src/jit_armv6m.erl");
85+
_Static_assert(offsetof(Context, fr) == 0x74, "ctx->fr is 0x74 in jit/src/jit_armv6m.erl");
86+
_Static_assert(offsetof(Context, bs) == 0x78, "ctx->bs is 0x78 in jit/src/jit_armv6m.erl");
87+
_Static_assert(offsetof(Context, bs_offset) == 0x7C, "ctx->bs_offset is 0x7C in jit/src/jit_armv6m.erl");
8888

8989
_Static_assert(offsetof(JITState, module) == 0x0, "jit_state->module is 0x0 in jit/src/jit_armv6m.erl");
9090
_Static_assert(offsetof(JITState, continuation) == 0x4, "jit_state->continuation is 0x4 in jit/src/jit_armv6m.erl");
@@ -93,12 +93,12 @@ _Static_assert(offsetof(JITState, remaining_reductions) == 0x8, "jit_state->rema
9393
_Static_assert(sizeof(size_t) == 4, "size_t is expected to be 32 bits");
9494

9595
#elif JIT_ARCH_TARGET == JIT_ARCH_RISCV32
96-
_Static_assert(offsetof(Context, e) == 0x14, "ctx->e is 0x14 in jit/src/jit_riscv32.erl");
97-
_Static_assert(offsetof(Context, x) == 0x18, "ctx->x is 0x18 in jit/src/jit_riscv32.erl");
98-
_Static_assert(offsetof(Context, cp) == 0x5C, "ctx->cp is 0x5C in jit/src/jit_riscv32.erl");
99-
_Static_assert(offsetof(Context, fr) == 0x60, "ctx->fr is 0x60 in jit/src/jit_riscv32.erl");
100-
_Static_assert(offsetof(Context, bs) == 0x64, "ctx->bs is 0x64 in jit/src/jit_riscv32.erl");
101-
_Static_assert(offsetof(Context, bs_offset) == 0x68, "ctx->bs_offset is 0x68 in jit/src/jit_riscv32.erl");
96+
_Static_assert(offsetof(Context, e) == 0x28, "ctx->e is 0x28 in jit/src/jit_riscv32.erl");
97+
_Static_assert(offsetof(Context, x) == 0x2C, "ctx->x is 0x2C in jit/src/jit_riscv32.erl");
98+
_Static_assert(offsetof(Context, cp) == 0x70, "ctx->cp is 0x70 in jit/src/jit_riscv32.erl");
99+
_Static_assert(offsetof(Context, fr) == 0x74, "ctx->fr is 0x74 in jit/src/jit_riscv32.erl");
100+
_Static_assert(offsetof(Context, bs) == 0x78, "ctx->bs is 0x78 in jit/src/jit_riscv32.erl");
101+
_Static_assert(offsetof(Context, bs_offset) == 0x7C, "ctx->bs_offset is 0x7C in jit/src/jit_riscv32.erl");
102102

103103
_Static_assert(offsetof(JITState, module) == 0x0, "jit_state->module is 0x0 in jit/src/jit_riscv32.erl");
104104
_Static_assert(offsetof(JITState, continuation) == 0x4, "jit_state->continuation is 0x4 in jit/src/jit_riscv32.erl");

0 commit comments

Comments
 (0)