Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't make const heap objects roots #223

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,20 @@ bool in_const_heap(struct gc_obj* obj) {
(uword)obj < (uword)__stop_const_heap;
}

static struct object* transport(struct gc_obj* from, struct gc_heap* heap) {
assert(!in_const_heap(from));
struct gc_obj* to = is_forwarded(from) ? forwarded(from) : copy(heap, from);
return heap_tag((uintptr_t)to);
}

void visit_root(struct object** pointer, struct gc_heap* heap) {
if (!is_heap_object(*pointer)) {
return;
}
struct gc_obj* from = as_heap_object(*pointer);
*pointer = transport(from, heap);
}

void visit_field(struct object** pointer, struct gc_heap* heap) {
if (!is_heap_object(*pointer)) {
return;
Expand All @@ -223,8 +237,7 @@ void visit_field(struct object** pointer, struct gc_heap* heap) {
if (in_const_heap(from)) {
return;
}
struct gc_obj* to = is_forwarded(from) ? forwarded(from) : copy(heap, from);
*pointer = heap_tag((uintptr_t)to);
*pointer = transport(from, heap);
}

static bool in_heap(struct gc_heap* heap, struct gc_obj* obj) {
Expand Down Expand Up @@ -259,7 +272,7 @@ static NEVER_INLINE void heap_verify(struct gc_heap* heap) {
void collect_no_verify(struct gc_heap* heap) {
flip(heap);
uintptr_t scan = heap->hp;
trace_roots(heap, visit_field);
trace_roots(heap, visit_root);
while (scan < heap->hp) {
struct gc_obj* obj = (struct gc_obj*)scan;
scan += align_size(trace_heap_object(obj, heap, visit_field));
Expand Down Expand Up @@ -683,8 +696,19 @@ void pop_handles(void* local_handles) {
struct handle_scope local_handles __attribute__((__cleanup__(pop_handles))); \
local_handles.base = handles;
#define GC_PROTECT(x) \
assert(handles != handles_end); \
(*handles++) = (struct object**)(&x)
do { \
/* TODO(max): Determine if it's worth it to have this fast path or if it's \
* just cluttering the code and should be done in a more advanced \
* compiler. */ \
if (!is_heap_object(x)) { \
break; \
} \
if (in_const_heap(as_heap_object(x))) { \
break; \
} \
assert(handles != handles_end); \
(*handles++) = (struct object**)(&x); \
} while (0)
#define GC_HANDLE(type, name, val) \
type name = val; \
GC_PROTECT(name)
Expand Down
Loading