Skip to content

Commit 74ec2fc

Browse files
committed
feat: mark all root objects and values (users'program and compiler ones)
1 parent eb4e7c8 commit 74ec2fc

9 files changed

Lines changed: 113 additions & 2 deletions

File tree

src/common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ typedef uint32_t u32;
1414
#define DEBUG_PRINT_CODE
1515
#define DEBUG_TRACE_EXECUTION
1616

17+
#define DEBUG_STRESS_GC
18+
#define DEBUG_LOG_GC
19+
1720
#endif

src/compiler.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "chunk.h"
77
#include "common.h"
88
#include "compiler.h"
9+
#include "memory.h"
910
#include "object.h"
1011
#include "scanner.h"
1112
#include "value.h"
@@ -986,3 +987,13 @@ ObjFunction* compile(const char* source)
986987
ObjFunction* function = end_compiler();
987988
return parser.had_error ? NULL : function;
988989
}
990+
991+
void mark_compiler_roots()
992+
{
993+
Compiler* compiler = current;
994+
while (compiler != NULL)
995+
{
996+
mark_object((Obj*)compiler->function);
997+
compiler = compiler->enclosing;
998+
}
999+
}

src/compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
#include "object.h"
66

77
ObjFunction* compile(const char* source);
8+
void mark_compiler_roots();
89

910
#endif

src/memory.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
#include <stdlib.h>
22

33
#include "chunk.h"
4+
#include "compiler.h"
45
#include "memory.h"
56
#include "object.h"
7+
#include "table.h"
68
#include "value.h"
79
#include "vm.h"
810

11+
#ifdef DEBUG_LOG_GC
12+
#include "debug.h"
13+
#include <stdio.h>
14+
#endif
15+
916
void* reallocate(void* pointer, size_t old_size, size_t new_size)
1017
{
18+
if (new_size > old_size)
19+
{
20+
#ifdef DEBUG_PRINT_CODE
21+
collect_garbage();
22+
#endif
23+
}
1124
if (new_size == 0)
1225
{
1326
free(pointer);
@@ -20,8 +33,35 @@ void* reallocate(void* pointer, size_t old_size, size_t new_size)
2033
return result;
2134
}
2235

36+
void mark_object(Obj* object)
37+
{
38+
if (object == NULL)
39+
return;
40+
41+
#ifdef DEBUG_LOG_GC
42+
printf("%p mark ", (void*)object);
43+
print_value(OBJ_VAL(object));
44+
printf("\n");
45+
#endif
46+
47+
object->is_marked = true;
48+
}
49+
50+
void mark_value(Value value)
51+
{
52+
if (!IS_OBJ(value))
53+
return;
54+
55+
mark_object(AS_OBJ(value));
56+
}
57+
2358
static void free_object(Obj* object)
2459
{
60+
61+
#ifdef DEBUG_LOG_GC
62+
printf("%p free type %d\n", (void*)object, object->type);
63+
#endif
64+
2565
switch (object->type)
2666
{
2767
case OBJ_CLOSURE:
@@ -57,6 +97,7 @@ static void free_object(Obj* object)
5797
}
5898
}
5999
}
100+
60101
void free_objects()
61102
{
62103
Obj* object = vm.objects;
@@ -67,3 +108,38 @@ void free_objects()
67108
object = next;
68109
}
69110
}
111+
112+
static void mark_roots()
113+
{
114+
for (Value* slot = vm.stack; slot < vm.stack_top; slot++)
115+
{
116+
mark_value(*slot);
117+
}
118+
119+
for (int i = 0; i < vm.frame_count; i++)
120+
{
121+
mark_object((Obj*)&vm.frames[i].closure);
122+
}
123+
124+
// WALKING A LINKED LIST
125+
for (ObjUpvalue* upvalue = vm.open_upvalues; upvalue != NULL; upvalue = upvalue->next)
126+
{
127+
mark_object((Obj*)upvalue);
128+
}
129+
130+
mark_table(&vm.globals);
131+
mark_compiler_roots();
132+
}
133+
134+
void collect_garbage()
135+
{
136+
#ifdef DEBUG_LOG_GC
137+
printf("-- GC Begins \n");
138+
#endif
139+
140+
mark_roots();
141+
142+
#ifdef DEBUG_LOG_GC
143+
printf("-- GC Ends \n");
144+
#endif
145+
}

src/memory.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define clox_memory_h
33

44
#include "common.h"
5+
#include "value.h"
56

67
#define ALLOCATE(type, count) (type*)reallocate(NULL, 0, sizeof(type) * (count))
78

@@ -17,6 +18,9 @@
1718
reallocate(pointer, sizeof(type) * (oldCount), 0)
1819

1920
void* reallocate(void* pointer, size_t old_size, size_t new_size);
21+
void mark_object(Obj* object);
22+
void mark_value(Value value);
23+
void collect_garbage();
2024
void free_objects();
2125

2226
#endif

src/object.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ static Obj* allocate_object(size_t size, ObjType type)
1818
Obj* object = (Obj*)reallocate(NULL, 0, size);
1919
object->type = type;
2020
object->next = vm.objects;
21+
object->is_marked = false;
2122
vm.objects = object;
2223

24+
#ifdef DEBUG_LOG_GC
25+
printf("%p allocate %ld for %d\n", (void*)object, size, type);
26+
#endif
27+
2328
return object;
2429
}
2530

src/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef enum
3232
struct Obj
3333
{
3434
ObjType type;
35+
bool is_marked;
3536
struct Obj* next;
3637
};
3738

src/table.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,13 @@ ObjString* table_find_string(Table* table, const char* chars, int length,
161161
index = (index + 1) % table->capacity;
162162
}
163163
}
164+
165+
void mark_table(Table* table)
166+
{
167+
for (int i = 0; i < table->capacity; i++)
168+
{
169+
Entry* entry = &table->entries[i];
170+
mark_object((Obj*)entry->key);
171+
mark_value(entry->value);
172+
}
173+
}

src/table.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ bool table_get(Table* table, ObjString* key, Value* value);
2323
bool table_set(Table* table, ObjString* key, Value value);
2424
bool table_delete(Table* table, ObjString* key);
2525
void table_add_all(Table* from, Table* to);
26-
ObjString* table_find_string(Table* table, const char* chars, int length,
27-
u32 hash);
26+
ObjString* table_find_string(Table* table, const char* chars, int length, u32 hash);
27+
void mark_table(Table* table);
2828

2929
#endif

0 commit comments

Comments
 (0)