Skip to content

Commit b63afa9

Browse files
committed
tmp
Signed-off-by: Shaw Summa <[email protected]>
1 parent 45bf363 commit b63afa9

File tree

13 files changed

+276
-256
lines changed

13 files changed

+276
-256
lines changed

main/minivm.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "../vm/vm.h"
44
#include "../vm/ir.h"
55
#include "../vm/io.h"
6+
#include "../vm/gc.h"
67
#include "../vm/std.h"
78
#include "../vm/lua/repl.h"
89

@@ -70,9 +71,11 @@ __attribute__((no_instrument_function)) int main(int argc, char **argv) {
7071
exit(1);
7172
}
7273
if (echo) {
73-
vm_io_buffer_t buf = {0};
74-
vm_io_buffer_obj_debug(&buf, 0, "", value, NULL);
75-
printf("%.*s", (int)buf.len, buf.buf);
74+
vm_io_buffer_t *buf = vm_io_buffer_new();
75+
vm_io_buffer_obj_debug(buf, 0, "", value, NULL);
76+
printf("%.*s", (int)buf->len, buf->buf);
77+
vm_free(buf->buf);
78+
vm_free(buf);
7679
}
7780

7881
vm_free(src);

main/primes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
max_width = 60
44
n = 32
5-
ls = [4, 8, 16]
5+
ls = [1, 3, 7, 13]
66

77
with open('vm/primes.inc', 'w') as f:
88
p32 = 2 ** 32

vm/gc.c

Lines changed: 128 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "ir.h"
44
#include "primes.inc"
55

6+
#define vm_get_gc(vm) ((vm_gc_t *) (vm)->gc)
7+
68
struct vm_gc_objs_t;
79
struct vm_gc_table_cache_t;
810
struct vm_gc_t;
@@ -25,181 +27,205 @@ struct vm_gc_table_cache_t {
2527

2628
struct vm_gc_t {
2729
size_t last;
30+
vm_gc_objs_t keep;
31+
vm_gc_objs_t todo;
2832
vm_gc_objs_t objs;
2933
};
3034

31-
static inline vm_gc_objs_add(vm_gc_objs_t *restrict objs, vm_obj_t obj) {
35+
static inline void vm_gc_objs_push(vm_gc_objs_t *restrict objs, vm_obj_t obj) {
3236
if (objs->len + 1 >= objs->alloc) {
3337
objs->alloc = (objs->len) * VM_GC_FACTOR + 1;
3438
objs->objs = vm_realloc(objs->objs, sizeof(vm_obj_t) * objs->alloc);
3539
}
3640
objs->objs[objs->len++] = obj;
3741
}
3842

39-
static inline void vm_gc_mark_obj(vm_obj_t obj);
43+
static inline vm_obj_t vm_gc_objs_pop(vm_gc_objs_t *restrict objs) {
44+
return objs->objs[--objs->len];
45+
}
46+
47+
static inline bool vm_gc_objs_is_empty(vm_gc_objs_t *restrict objs) {
48+
return objs->len == 0;
49+
}
4050

41-
static inline void vm_gc_mark_arg(vm_ir_arg_t arg) {
51+
static inline void vm_gc_objs_clear(vm_gc_objs_t *restrict objs) {
52+
objs->len = 0;
53+
}
54+
55+
static inline void vm_gc_objs_free(vm_gc_objs_t *restrict objs) {
56+
vm_free(objs->objs);
57+
*objs = (vm_gc_objs_t) {
58+
.objs = NULL,
59+
};
60+
}
61+
62+
static inline void vm_gc_mark_obj(vm_t *vm, vm_obj_t obj);
63+
64+
static inline void vm_gc_mark_arg(vm_t *vm, vm_ir_arg_t arg) {
4265
if (arg.type == VM_IR_ARG_TYPE_LIT) {
43-
vm_gc_mark_obj(arg.lit);
66+
vm_gc_mark_obj(vm, arg.lit);
4467
}
4568
}
4669

47-
static inline void vm_gc_mark_block(vm_ir_block_t *block) {
48-
if (!block->mark) {
49-
block->mark = true;
70+
static inline void vm_gc_mark_block(vm_t *vm, vm_ir_block_t *block) {
71+
if (!block->header.mark) {
72+
block->header.mark = true;
5073
for (size_t j = 0; j < block->len; j++) {
5174
vm_ir_instr_t *instr = &block->instrs[j];
5275
for (size_t k = 0; instr->args[k].type != VM_IR_ARG_TYPE_NONE; k++) {
53-
vm_gc_mark_arg(instr->args[k]);
76+
vm_gc_mark_arg(vm, instr->args[k]);
5477
}
5578
}
5679
for (size_t j = 0; j < 2 && block->branch.targets[j] != NULL; j++) {
57-
vm_gc_mark_block(block->branch.targets[j]);
80+
vm_gc_mark_block(vm, block->branch.targets[j]);
5881
}
5982
for (size_t k = 0; block->branch.args[k].type != VM_IR_ARG_TYPE_NONE; k++) {
60-
vm_gc_mark_arg(block->branch.args[k]);
83+
vm_gc_mark_arg(vm, block->branch.args[k]);
84+
}
85+
vm_gc_mark_arg(vm, block->branch.out);
86+
}
87+
}
88+
89+
static inline void vm_gc_mark_run(vm_t *vm) {
90+
while (!vm_gc_objs_is_empty(&vm_get_gc(vm)->todo)) {
91+
vm_obj_t obj = vm_gc_objs_pop(&vm_get_gc(vm)->todo);
92+
if (vm_obj_is_string(obj)) {
93+
vm_io_buffer_t *buffer = vm_obj_get_string(obj);
94+
if (!buffer->header.mark) {
95+
buffer->header.mark = true;
96+
vm_gc_objs_push(&vm_get_gc(vm)->keep, obj);
97+
}
98+
} else if (vm_obj_is_closure(obj)) {
99+
vm_obj_closure_t *closure = vm_obj_get_closure(obj);
100+
if (!closure->header.mark) {
101+
closure->header.mark = true;
102+
vm_gc_objs_push(&vm_get_gc(vm)->keep, obj);
103+
for (size_t i = 0; i < closure->len; i++) {
104+
vm_gc_mark_obj(vm, closure->values[i]);
105+
}
106+
}
107+
vm_gc_mark_block(vm, closure->block);
108+
} else if (vm_obj_is_table(obj)) {
109+
vm_obj_table_t *table = vm_obj_get_table(obj);
110+
if (!table->header.mark) {
111+
table->header.mark = true;
112+
vm_gc_objs_push(&vm_get_gc(vm)->keep, obj);
113+
uint64_t len = vm_primes_table[table->size];
114+
vm_table_pair_t *pairs = table->pairs;
115+
for (size_t i = 0; i < len; i++) {
116+
vm_gc_mark_obj(vm, pairs[i].key);
117+
vm_gc_mark_obj(vm, pairs[i].value);
118+
}
119+
}
120+
} else if (vm_obj_is_block(obj)) {
121+
vm_gc_mark_block(vm, vm_obj_get_block(obj));
61122
}
62-
vm_gc_mark_arg(block->branch.out);
63123
}
64124
}
65125

126+
static inline void vm_gc_mark_obj(vm_t *vm, vm_obj_t obj) {
127+
vm_gc_objs_push(&vm_get_gc(vm)->todo, obj);
128+
}
66129

67-
static inline void vm_gc_mark_obj(vm_obj_t obj) {
130+
static inline void vm_gc_maybe_reset_obj(vm_t *vm, vm_obj_t obj) {
68131
if (vm_obj_is_string(obj)) {
69132
vm_io_buffer_t *buffer = vm_obj_get_string(obj);
70-
buffer->mark = true;
133+
if (!buffer->header.mark) {
134+
vm_free(buffer->buf);
135+
vm_free(buffer);
136+
} else {
137+
buffer->header.mark = false;
138+
}
71139
} else if (vm_obj_is_closure(obj)) {
72140
vm_obj_closure_t *closure = vm_obj_get_closure(obj);
73-
if (!closure->mark) {
74-
closure->mark = true;
75-
for (size_t i = 0; i < closure->len; i++) {
76-
vm_gc_mark_obj(closure->values[i]);
77-
}
141+
if (!closure->header.mark) {
142+
vm_free(closure);
143+
} else {
144+
closure->header.mark = false;
78145
}
79-
vm_gc_mark_block(closure->block);
80146
} else if (vm_obj_is_table(obj)) {
81147
vm_obj_table_t *table = vm_obj_get_table(obj);
82-
if (!table->mark) {
83-
table->mark = true;
84-
uint64_t len = vm_primes_table[table->size];
85-
vm_table_pair_t *pairs = table->pairs;
86-
for (size_t i = 0; i < len; i++) {
87-
vm_gc_mark_obj(pairs[i].key);
88-
vm_gc_mark_obj(pairs[i].value);
89-
}
148+
if (!table->header.mark) {
149+
vm_free(table->pairs);
150+
vm_free(table);
151+
} else {
152+
table->header.mark = false;
90153
}
91154
} else if (vm_obj_is_block(obj)) {
92-
vm_gc_mark_block(vm_obj_get_block(obj));
155+
vm_ir_block_t *block = vm_obj_get_block(obj);
156+
if (!block->header.mark) {
157+
for (size_t j = 0; j < block->len; j++) {
158+
vm_ir_instr_t instr = block->instrs[j];
159+
vm_free(instr.args);
160+
}
161+
vm_free(block->instrs);
162+
vm_free(block->branch.args);
163+
vm_free(block->code);
164+
vm_free(block);
165+
} else {
166+
block->header.mark = false;
167+
}
93168
}
94169
}
95170

96171
void vm_gc_mark(vm_t *vm, vm_obj_t *top) {
172+
vm_gc_objs_clear(&vm_get_gc(vm)->keep);
173+
97174
for (vm_ir_blocks_t *blocks = vm->blocks; blocks; blocks = blocks->next) {
98-
vm_gc_mark_block(blocks->block);
175+
vm_gc_mark_block(vm, blocks->block);
99176
}
100-
vm_gc_mark_obj(vm->std);
177+
vm_gc_mark_obj(vm, vm->std);
101178
for (vm_obj_t *head = vm->base; head < top; head++) {
102-
vm_gc_mark_obj(*head);
179+
vm_gc_mark_obj(vm, *head);
103180
}
104-
}
181+
vm_gc_mark_run(vm);
105182

106-
void vm_gc_sweep(vm_t *vm) {
107-
vm_gc_t *restrict gc = vm->gc;
108-
size_t write = 0;
109-
for (size_t i = 0; i < gc->objs.len; i++) {
110-
vm_obj_t obj = gc->objs.objs[i];
111-
if (vm_obj_is_string(obj)) {
112-
vm_io_buffer_t *buffer = vm_obj_get_string(obj);
113-
if (!buffer->mark) {
114-
vm_free(buffer->buf);
115-
vm_free(buffer);
116-
} else {
117-
buffer->mark = false;
118-
gc->objs.objs[write++] = obj;
119-
}
120-
} else if (vm_obj_is_closure(obj)) {
121-
vm_obj_closure_t *closure = vm_obj_get_closure(obj);
122-
if (!closure->mark) {
123-
vm_free(closure);
124-
} else {
125-
closure->mark = false;
126-
gc->objs.objs[write++] = obj;
127-
}
128-
} else if (vm_obj_is_table(obj)) {
129-
vm_obj_table_t *table = vm_obj_get_table(obj);
130-
if (!table->mark) {
131-
if (!table->pairs_auto) {
132-
vm_free(table->pairs);
133-
}
134-
vm_free(table);
135-
} else {
136-
table->mark = false;
137-
gc->objs.objs[write++] = obj;
138-
}
139-
} else if (vm_obj_is_block(obj)) {
140-
vm_ir_block_t *block = vm_obj_get_block(obj);
141-
if (!block->mark) {
142-
for (size_t j = 0; j < block->len; j++) {
143-
vm_ir_instr_t instr = block->instrs[j];
144-
vm_free(instr.args);
145-
}
146-
vm_free(block->instrs);
147-
vm_free(block->branch.args);
148-
vm_free(block->code);
149-
vm_free(block);
150-
} else {
151-
block->mark = false;
152-
gc->objs.objs[write++] = obj;
153-
}
154-
}
155-
}
156-
printf("gc %zu -> %zu\n", gc->objs.len, write);
157-
gc->objs.len = write;
158-
size_t next = write * VM_GC_FACTOR;
159-
if (next >= gc->last) {
160-
gc->last = next;
183+
printf("%zu -> %zu\n", vm_get_gc(vm)->objs.len, vm_get_gc(vm)->keep.len);
184+
185+
for (size_t i = 0; i < vm_get_gc(vm)->objs.len; i++) {
186+
vm_gc_maybe_reset_obj(vm, vm_get_gc(vm)->objs.objs[i]);
161187
}
188+
189+
vm_gc_objs_t old_keep = vm_get_gc(vm)->keep;
190+
vm_gc_objs_t old_objs = vm_get_gc(vm)->objs;
191+
vm_get_gc(vm)->objs = old_keep;
192+
vm_get_gc(vm)->keep = old_objs;
193+
194+
vm_get_gc(vm)->last = vm_get_gc(vm)->objs.len * VM_GC_FACTOR;
162195
}
163196

164197
vm_obj_table_t *vm_table_new(vm_t *vm) {
165-
vm_gc_t *restrict gc = vm->gc;
166198
vm_obj_table_t *ret = vm_malloc(sizeof(vm_obj_table_t) + sizeof(vm_table_pair_t) * vm_primes_table[0]);
167-
ret->pairs = (vm_table_pair_t *)&ret[1];
199+
ret->pairs = vm_malloc(sizeof(vm_table_pair_t) * vm_primes_table[0]);
168200
memset(ret->pairs, VM_EMPTY_BYTE, sizeof(vm_table_pair_t) * vm_primes_table[0]);
169201
ret->size = 0;
170202
ret->used = 0;
171203
ret->len = 0;
172-
ret->mark = false;
173-
ret->pairs_auto = true;
204+
ret->header.mark = false;
174205
vm_gc_add(vm, vm_obj_of_table(ret));
175206
return ret;
176207
}
177208

178209
void vm_gc_run(vm_t *vm, vm_obj_t *top) {
179-
vm_gc_t *restrict gc = vm->gc;
180-
if (gc->last >= gc->objs.len) {
210+
if (vm_get_gc(vm)->last >= vm_get_gc(vm)->objs.len) {
181211
return;
182212
}
183213
vm_gc_mark(vm, top);
184-
vm_gc_sweep(vm);
185214
}
186215

187216
void vm_gc_init(vm_t *vm) {
188217
vm->gc = vm_malloc(sizeof(vm_gc_t));
189-
vm_gc_t *restrict gc = vm->gc;
190-
*gc = (vm_gc_t){
218+
*vm_get_gc(vm) = (vm_gc_t){
191219
.last = VM_GC_MIN,
192220
};
193221
}
194222

195223
void vm_gc_deinit(vm_t *vm) {
196-
vm_gc_sweep(vm);
197-
vm_gc_t *gc = vm->gc;
198-
vm_free(gc->objs.objs);
199-
vm_free(vm->gc);
224+
vm_gc_objs_free(&vm_get_gc(vm)->objs);
225+
// vm_gc_objs_free(&gc->black);
226+
vm_free(vm_get_gc(vm));
200227
}
201228

202229
void vm_gc_add(vm_t *vm, vm_obj_t obj) {
203-
vm_gc_t *restrict gc = vm->gc;
204-
vm_gc_objs_add(&gc->objs, obj);
230+
vm_gc_objs_push(&vm_get_gc(vm)->objs, obj);
205231
}

vm/gc.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
#include "lib.h"
55

6-
void vm_gc_mark(vm_t *vm, vm_obj_t *top);
7-
void vm_gc_sweep(vm_t *vm);
8-
96
void vm_gc_run(vm_t *vm, vm_obj_t *top);
107
void vm_gc_init(vm_t *vm);
118
void vm_gc_deinit(vm_t *vm);

vm/io.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ void vm_io_buffer_format(vm_io_buffer_t *buf, const char *fmt, ...) {
4848
}
4949

5050
char *vm_io_vformat(const char *fmt, va_list ap) {
51-
vm_io_buffer_t buf = (vm_io_buffer_t){0};
51+
vm_io_buffer_t buf;
52+
memset(&buf, 0, sizeof(vm_io_buffer_t));
5253
vm_io_buffer_vformat(&buf, fmt, ap);
5354
return buf.buf;
5455
}
@@ -179,10 +180,11 @@ void vm_io_buffer_obj_debug(vm_io_buffer_t *out, size_t indent, const char *pref
179180
vm_io_buffer_obj_debug(out, indent + 1, buf, p.value, &next);
180181
}
181182
else if (vm_obj_is_string(p.key)) {
182-
vm_io_buffer_t buf = {0};
183-
vm_io_buffer_format(&buf, "%s = ", vm_obj_get_string(p.key)->buf);
184-
vm_io_buffer_obj_debug(out, indent + 1, buf.buf, p.value, &next);
185-
vm_free(buf.buf);
183+
vm_io_buffer_t *buf = vm_io_buffer_new();
184+
vm_io_buffer_format(buf, "%s = ", vm_obj_get_string(p.key)->buf);
185+
vm_io_buffer_obj_debug(out, indent + 1, buf->buf, p.value, &next);
186+
vm_free(buf->buf);
187+
vm_free(buf);
186188
} else {
187189
vm_io_indent(out, indent + 1, "");
188190
vm_io_buffer_format(out, "pair {\n");

0 commit comments

Comments
 (0)