Skip to content

Commit 1c58fb2

Browse files
committed
added gc i think, will have to check
1 parent 4d208a4 commit 1c58fb2

28 files changed

+235
-84
lines changed

include/squire/attributes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
#else
9090
# define SQ_LIKELY(x) (!!(x))
9191
#endif /* SQ_HAS_BUILTIN(__builtin_expect) */
92-
#define SQ_UNLIKELY(x) SQ_LIKELY(!(x))
92+
#define SQ_UNLIKELY(x) (!SQ_LIKELY(!(x)))
9393

9494
#if SQ_HAS_BUILTIN(__builtin_unreachable)
9595
# define SQ_UNREACHABLE __builtin_unreachable()

include/squire/basic.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define SQ_BASIC_H
33

44
#include <squire/attributes.h>
5+
#include <squire/valuedecl.h>
56

67
#define SQ_VALUE_SIZE 64
78
#define SQ_VALUE_ALIGNMENT 8
@@ -13,12 +14,16 @@
1314
SQ_STATIC_ASSERT(sizeof(type) <= SQ_VALUE_SIZE, \
1415
"type '" #type "' is too large (" SQ_TO_STRING_(SQ_VALUE_SIZE))
1516

17+
enum foo { x };
1618
struct sq_basic {
1719
SQ_ALIGNAS(SQ_VALUE_ALIGNMENT) char _blank;
18-
bool marked: 1;
19-
} __align;
20+
int marked: 1;
21+
int in_use: 1;
22+
enum sq_genus_tag genus: SQ_GENUS_TAG_BITS;
23+
};
2024

21-
#define SQ_BASIC_DEFAULT ((struct sq_basic) { .marked = 0 })
25+
#define SQ_STATIC_BASIC(kind) ((struct sq_basic) { .marked = 0, .in_use = 1, \
26+
.genus = SQ_TAG_FOR(kind) })
2227
#define SQ_GUARD_MARK(what) do { if ((what)->basic.marked) return; (what)->basic.marked = 1; } while(0)
2328

2429
#endif

include/squire/exception.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <squire/shared.h>
1111
#include <stdio.h>
1212
#include <errno.h>
13+
#include <string.h>
1314

1415
// jmp_buf redo_location;
1516
extern jmp_buf exception_handlers[SQ_NUM_EXCEPTION_HANDLERS];

include/squire/gc.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef SQ_GC_H
2+
#define SQ_GC_H
3+
4+
#include <squire/program.h>
5+
#include <squire/valuedecl.h>
6+
7+
void sq_gc_init(long long heap_size, struct sq_program *program);
8+
void sq_gc_start(void);
9+
void sq_gc_teardown(void);
10+
void *sq_gc_malloc(enum sq_genus_tag genus); // allocates enough to store one value
11+
12+
#endif

include/squire/journey.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,24 @@ struct sq_journey {
4444

4545
struct sq_journey_pattern *patterns;
4646
};
47+
48+
struct sq_stackframe {
49+
unsigned ip;
50+
const struct sq_journey *journey;
51+
const struct sq_journey_pattern *pattern;
52+
sq_value *locals;
53+
};
54+
55+
#ifndef SQ_MAX_STACKFRAME_COUNT
56+
# define SQ_MAX_STACKFRAME_COUNT 10000000
57+
#endif
58+
extern struct sq_stackframe sq_stackframes[SQ_MAX_STACKFRAME_COUNT];
59+
extern unsigned sq_current_stackframe;
60+
61+
4762
SQ_VALUE_ASSERT_SIZE(struct sq_journey);
4863

64+
void sq_stackframe_mark(struct sq_stackframe *stackframe);
4965
void sq_journey_mark(struct sq_journey *journey);
5066
void sq_journey_deallocate(struct sq_journey *journey);
5167

include/squire/program.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ struct sq_program {
99
struct sq_journey *main;
1010
};
1111

12+
void sq_program_mark(struct sq_program *);
1213
void sq_program_compile(struct sq_program *program, const char *stream);
1314
void sq_program_run(struct sq_program *program, unsigned argc, const char **argv);
1415
void sq_program_finish(struct sq_program *program);

include/squire/shared.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#ifndef SQ_SHARED_H
22
#define SQ_SHARED_H
33

4-
#include <squire/valuedecl.h>
54
#include <squire/attributes.h>
5+
#include <squire/gc.h>
66
#include <stdio.h>
77
#include <stdlib.h>
88

@@ -20,11 +20,15 @@
2020

2121
#define sq_sizeof_array(kind, length) (sizeof(kind) * (length))
2222
#define sq_mallocz(kind) ((kind *) sq_calloc(1, sizeof(kind)))
23-
#define sq_malloc_single(kind) ((kind *) sq_malloc(sizeof(kind)))
24-
#define sq_malloc_vec(kind, length) ((kind *) sq_malloc(sq_sizeof_array(kind, (length))))
23+
#define sq_mallocv(kind) (assert(sizeof(kind) <= SQ_VALUE_SIZE),\
24+
(kind *) sq_gc_malloc( \
25+
SQ_TAG_FOR(kind) \
26+
))
27+
#define sq_malloc_single(kind) ((kind *) sq_malloc_heap(sizeof(kind)))
28+
#define sq_malloc_vec(kind, length) ((kind *) sq_malloc_heap(sq_sizeof_array(kind, (length))))
2529
#define sq_realloc_vec(kind, ptr, length) ((kind *) sq_realloc((ptr), sq_sizeof_array(kind, (length))))
2630

27-
void *sq_malloc(size_t size)
31+
void *sq_malloc_heap(size_t size)
2832
SQ_NODISCARD
2933
#if SQ_HAS_ATTRIBUTE(malloc)
3034
SQ_ATTR(malloc)

include/squire/text.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ static inline struct sq_text *sq_text_new(char *ptr) {
2323
#define SQ_TEXT_STATIC(literal) \
2424
{ \
2525
.ptr = (literal), \
26-
.basic = SQ_BASIC_DEFAULT, \
26+
.basic = SQ_STATIC_BASIC(struct sq_text), \
2727
.length = sizeof(literal) - 1, \
2828
}
2929
// TODO: init basic
3030

3131
static inline void sq_text_mark(struct sq_text *string) {
32-
(void) string;
32+
string->basic.marked = 1;
3333
}
3434

3535
void sq_text_deallocate(struct sq_text *string);

include/squire/value.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88

99
#include <squire/valuedecl.h>
1010

11+
static inline sq_value sq_value_new_ptr_unchecked(void *ptr, enum sq_genus_tag tag) {
12+
assert(tag != SQ_G_NUMERAL);
13+
return ((sq_value) ptr) | tag;
14+
}
15+
1116
static inline sq_value sq_value_new_numeral(sq_numeral numeral) {
1217
assert(numeral == (((sq_numeral) (((sq_value) numeral << SQ_VSHIFT)) >> SQ_VSHIFT)));
1318
return SQ_VMASK(((sq_value) numeral) << SQ_VSHIFT, SQ_G_NUMERAL);

include/squire/valuedecl.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,19 @@ enum sq_genus_tag {
2929
SQ_G_CODEX = 7,
3030
} SQ_CLOSED_ENUM;
3131

32-
#define SQ_VSHIFT 4
32+
#define SQ_TAG_FOR(kind) (_Generic(&(kind){0}, \
33+
struct sq_other *: SQ_G_OTHER, \
34+
struct sq_text *: SQ_G_TEXT, \
35+
struct sq_form *: SQ_G_FORM, \
36+
struct sq_imitation *: SQ_G_IMITATION, \
37+
struct sq_journey *: SQ_G_JOURNEY, \
38+
struct sq_book *: SQ_G_BOOK, \
39+
struct sq_codex *: SQ_G_CODEX \
40+
))
41+
42+
43+
#define SQ_GENUS_TAG_BITS 3
44+
#define SQ_VSHIFT ((SQ_GENUS_TAG_BITS) + 1)
3345
#define SQ_VMASK_BITS ((1<<SQ_VSHIFT)-1)
3446
SQ_STATIC_ASSERT((SQ_VMASK_BITS & SQ_G_CODEX) == SQ_G_CODEX, "oops?");
3547

src/exception.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <squire/text.h>
33
#include <squire/value.h>
44
#include <squire/form.h>
5+
#include <squire/other/other.h>
56

67
#include <stdarg.h>
78
#include <stdlib.h>
@@ -18,7 +19,7 @@ struct sq_form sq_exception_form, sq_io_exception_form;
1819
struct sq_form_vtable sq_exception_form_vtable, sq_io_exception_form_vtable;
1920

2021
void sq_exception_init(struct sq_program *program) {
21-
sq_exception_form.basic = SQ_BASIC_DEFAULT;
22+
sq_exception_form.basic = SQ_STATIC_BASIC(struct sq_form);
2223
sq_exception_form.vt = &sq_exception_form_vtable;
2324
sq_exception_form.vt->name = "Rock";
2425

@@ -29,7 +30,7 @@ void sq_exception_init(struct sq_program *program) {
2930

3031
sq_exception_form.vt->nchanges = 1;
3132
sq_exception_form.vt->changes = sq_malloc_single(struct sq_journey *);
32-
struct sq_journey *to_text = sq_exception_form.vt->changes[0] = sq_malloc_single(struct sq_journey);
33+
struct sq_journey *to_text = sq_exception_form.vt->changes[0] = sq_mallocv(struct sq_journey);
3334

3435
(void) to_text;
3536
(void) program;

src/gc.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include <squire/gc.h>
2+
#include <squire/basic.h>
3+
#include <squire/shared.h>
4+
#include <sys/mman.h>
5+
6+
struct anyvalue {
7+
struct sq_basic basic;
8+
SQ_ALIGNAS(SQ_VALUE_ALIGNMENT) char _ignored[SQ_VALUE_SIZE - SQ_VALUE_ALIGNMENT];
9+
};
10+
_Static_assert(sizeof(struct anyvalue) == SQ_VALUE_SIZE, "size isnt equal");
11+
12+
struct sq_program *program;
13+
struct anyvalue *heap_start, *heap;
14+
long long heap_size;
15+
16+
17+
void sq_gc_init(long long heap_size_, struct sq_program *program_) {
18+
heap_size = heap_size_ * SQ_VALUE_SIZE;
19+
program = program_;
20+
heap_start = heap = mmap(NULL, heap_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
21+
22+
if (heap == MAP_FAILED)
23+
sq_throw_io("unable to mmap %zu bytes for the heap", heap_size);
24+
}
25+
26+
void sq_gc_teardown(void) {
27+
if (munmap(heap_start, heap_size))
28+
sq_throw_io("unable to un mmap %zu bytes for the heap", heap_size);
29+
}
30+
31+
void *sq_gc_malloc(enum sq_genus_tag genus) {
32+
if (SQ_UNLIKELY((heap_size / SQ_VALUE_SIZE) <= (heap - heap_start))) {
33+
sq_gc_start();
34+
35+
if (SQ_UNLIKELY((heap_size / SQ_VALUE_SIZE) <= heap - heap_start))
36+
sq_throw("heap exhausted.");
37+
}
38+
39+
while (heap->basic.in_use) ++heap;
40+
heap->basic.genus = genus;
41+
heap->basic.in_use = 1;
42+
return heap++;
43+
}
44+
45+
void sq_gc_start(void) {
46+
// for (struct anyvalue *ptr = heap_start; ptr < heap; ++ptr) {
47+
// if (!ptr->basic.in_use) continue;
48+
// sq_value_mark(sq_value_new_ptr_unchecked((void *) ptr, ptr->basic.genus));
49+
// }
50+
51+
sq_program_mark(program);
52+
53+
for (struct anyvalue *ptr = heap_start; ptr < heap; ++ptr) {
54+
if (!ptr->basic.in_use) continue;
55+
if (ptr->basic.marked) {
56+
ptr->basic.marked = 0;
57+
continue;
58+
}
59+
60+
sq_value_deallocate(sq_value_new_ptr_unchecked((void *) ptr, ptr->basic.genus));
61+
ptr->basic.in_use = 0;
62+
}
63+
64+
heap = heap_start;
65+
}

src/main.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <squire/program.h>
22
#include <squire/shared.h>
3+
#include <squire/gc.h>
34

45
#include <stdio.h>
56
#include <string.h>
@@ -14,6 +15,10 @@ int main(int argc, const char **argv) {
1415
}
1516

1617
struct sq_program program;
18+
#ifndef SQ_GC_HEAP_SIZE
19+
# define SQ_GC_HEAP_SIZE 100000000
20+
#endif
21+
sq_gc_init(SQ_GC_HEAP_SIZE, &program);
1722

1823
if (argv[1][1] == 'e') {
1924
sq_program_compile(&program, argv[2]);
@@ -22,9 +27,10 @@ int main(int argc, const char **argv) {
2227
sq_program_compile(&program, contents);
2328
free(contents);
2429
}
25-
2630
sq_program_run(&program, argc - 3, argv + 3);
31+
sq_gc_start();
2732
sq_program_finish(&program);
33+
sq_gc_teardown();
2834

2935
return 0;
3036
}

src/other/io/io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <squire/program.h>
55

66
static struct sq_other sq_io_kingdom_other = {
7-
.basic = SQ_BASIC_DEFAULT,
7+
.basic = SQ_STATIC_BASIC(struct sq_other),
88
.kind = SQ_OK_KINGDOM,
99
.kingdom = {
1010
.name = "Io"

src/other/io/scroll.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ void sq_scroll_init(struct sq_scroll *scroll, const char *filename, const char *
3030

3131
struct sq_other *other;
3232
#define NEW_JOURNEY(_name, _nargs) \
33-
_name##_journey = sq_value_new_other(other = sq_malloc_single(struct sq_other)); \
34-
other->basic = SQ_BASIC_DEFAULT; \
33+
_name##_journey = sq_value_new_other(other = sq_mallocv(struct sq_other)); \
3534
other->kind = SQ_OK_BUILTIN_JOURNEY; \
3635
other->builtin_journey.name = "Scroll."#_name; \
3736
other->builtin_journey.nargs = _nargs; \

src/other/other.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,6 @@ void sq_other_deallocate(struct sq_other *other) {
9393
case SQ_OK_PAT_HELPER:
9494
break;
9595
}
96-
97-
free(other);
9896
}
9997

10098
const char *sq_other_typename(const struct sq_other *other) {

src/posix.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct _nothing_to_see_here;
99
char *strdup(char *str) {
1010
size_t length = strlen(str) + 1;
1111

12-
return memcpy(sq_malloc(length), str, length);
12+
return memcpy(sq_malloc_heap(length), str, length);
1313
}
1414

1515
char *strndup(char *str, size_t maxlen) {
@@ -18,7 +18,7 @@ char *strndup(char *str, size_t maxlen) {
1818
if (length < maxlen)
1919
return strdup(str);
2020

21-
char *result = sq_malloc(maxlen);
21+
char *result = sq_malloc_heap(maxlen);
2222
memcpy(result, str, maxlen);
2323
result[maxlen] = '\0';
2424

src/program/compile.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ static void compile_kingdom_declaration(struct sq_code *code, struct kingdom_dec
411411
// } *subjects;
412412
// };
413413

414-
// struct sq_kingdom *kingdom = sq_malloc(sizeof(struct sq_kingdom));
414+
// struct sq_kingdom *kingdom = sq_malloc_heap(sizeof(struct sq_kingdom));
415415
// kingdom->name = kdecl->name;
416416
// kingdom->nsubjects = kingdom->subject_cap = kdecl->nsubjects;
417417
// kingdom->subjects = sq_malloc_vec(struct sq_kingdom_subject, kingdom->nsubjects);
@@ -1519,10 +1519,9 @@ static void compile_journey_pattern(
15191519
}
15201520

15211521
static struct sq_journey *compile_journey(struct journey_declaration *jd, bool is_method) {
1522-
struct sq_journey *journey = sq_malloc_single(struct sq_journey);
1522+
struct sq_journey *journey = sq_mallocv(struct sq_journey);
15231523

15241524
journey->name = jd->name;
1525-
journey->basic = SQ_BASIC_DEFAULT;
15261525
journey->npatterns = jd->npatterns;
15271526
journey->program = program;
15281527
journey->is_method = is_method;
@@ -1573,7 +1572,7 @@ void sq_program_compile(struct sq_program *program_, const char *stream) {
15731572
setup_globals();
15741573

15751574
program = program_;
1576-
program->nglobals = 1;
1575+
program->nglobals = 0;
15771576
program->globals = NULL;
15781577

15791578
struct journey_declaration maindecl = {
@@ -1598,4 +1597,5 @@ void sq_program_compile(struct sq_program *program_, const char *stream) {
15981597

15991598
for (unsigned i = 0; i < program->nglobals; ++i)
16001599
program->globals[i] = globals.ary[i].value;
1600+
16011601
}

src/program/macro.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ static void parse_transcribe(void) {
311311
if (errno) perror("cannot get file size"), exit(1);
312312

313313
size_t stream_len = strlen(sq_stream);
314-
char *new_stream = sq_malloc(stream_len + file_size + 1);
314+
char *new_stream = sq_malloc_heap(stream_len + file_size + 1);
315315
fread(new_stream, 1, file_size, file);
316316

317317
if (errno) perror("cannot get read file contents"), exit(1);

0 commit comments

Comments
 (0)