mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-12 14:50:19 +02:00
Merge remote-tracking branch 'whippet/main' into wip-whippet
This commit is contained in:
commit
fb5a99c752
10 changed files with 145 additions and 71 deletions
|
@ -88,8 +88,6 @@ static inline void gc_update_alloc_table(struct gc_ref obj, size_t size,
|
||||||
alloc[0] = begin_pattern | end_pattern;
|
alloc[0] = begin_pattern | end_pattern;
|
||||||
} else {
|
} else {
|
||||||
alloc[0] = begin_pattern;
|
alloc[0] = begin_pattern;
|
||||||
if (granules > 2)
|
|
||||||
memset(alloc + 1, 0, granules - 2);
|
|
||||||
alloc[granules - 1] = end_pattern;
|
alloc[granules - 1] = end_pattern;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -22,7 +22,6 @@ GC_EMBEDDER_API inline int gc_is_valid_conservative_ref_displacement(uintptr_t d
|
||||||
GC_EMBEDDER_API inline size_t gc_finalizer_priority_count(void);
|
GC_EMBEDDER_API inline size_t gc_finalizer_priority_count(void);
|
||||||
|
|
||||||
GC_EMBEDDER_API inline int gc_extern_space_visit(struct gc_extern_space *space,
|
GC_EMBEDDER_API inline int gc_extern_space_visit(struct gc_extern_space *space,
|
||||||
struct gc_edge edge,
|
|
||||||
struct gc_ref ref) GC_ALWAYS_INLINE;
|
struct gc_ref ref) GC_ALWAYS_INLINE;
|
||||||
GC_EMBEDDER_API inline void gc_extern_space_start_gc(struct gc_extern_space *space,
|
GC_EMBEDDER_API inline void gc_extern_space_start_gc(struct gc_extern_space *space,
|
||||||
int is_minor_gc);
|
int is_minor_gc);
|
||||||
|
@ -51,23 +50,29 @@ GC_EMBEDDER_API inline void gc_trace_heap_roots(struct gc_heap_roots *roots,
|
||||||
void *trace_data);
|
void *trace_data);
|
||||||
|
|
||||||
GC_EMBEDDER_API inline void
|
GC_EMBEDDER_API inline void
|
||||||
gc_trace_mutator_conservative_roots(struct gc_mutator_roots *roots,
|
gc_trace_mutator_pinned_roots(struct gc_mutator_roots *roots,
|
||||||
void (*trace_range)(uintptr_t start,
|
void (*trace_pinned)(struct gc_ref ref,
|
||||||
uintptr_t end,
|
struct gc_heap *heap,
|
||||||
int possibly_interior,
|
void *data),
|
||||||
struct gc_heap *heap,
|
void (*trace_ambiguous)(uintptr_t start,
|
||||||
void *data),
|
uintptr_t end,
|
||||||
struct gc_heap *heap,
|
int possibly_interior,
|
||||||
void *data);
|
struct gc_heap *heap,
|
||||||
|
void *data),
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *data);
|
||||||
GC_EMBEDDER_API inline void
|
GC_EMBEDDER_API inline void
|
||||||
gc_trace_heap_conservative_roots(struct gc_heap_roots *roots,
|
gc_trace_heap_pinned_roots(struct gc_heap_roots *roots,
|
||||||
void (*trace_range)(uintptr_t start,
|
void (*trace_pinned)(struct gc_ref ref,
|
||||||
uintptr_t end,
|
struct gc_heap *heap,
|
||||||
int possibly_interior,
|
void *data),
|
||||||
struct gc_heap *heap,
|
void (*trace_ambiguous)(uintptr_t start,
|
||||||
void *data),
|
uintptr_t end,
|
||||||
struct gc_heap *heap,
|
int possibly_interior,
|
||||||
void *data);
|
struct gc_heap *heap,
|
||||||
|
void *data),
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *data);
|
||||||
|
|
||||||
GC_EMBEDDER_API inline uintptr_t gc_object_forwarded_nonatomic(struct gc_ref ref);
|
GC_EMBEDDER_API inline uintptr_t gc_object_forwarded_nonatomic(struct gc_ref ref);
|
||||||
GC_EMBEDDER_API inline void gc_object_forward_nonatomic(struct gc_ref ref,
|
GC_EMBEDDER_API inline void gc_object_forward_nonatomic(struct gc_ref ref,
|
||||||
|
|
|
@ -23,7 +23,6 @@ gc_is_valid_conservative_ref_displacement(uintptr_t displacement) {
|
||||||
|
|
||||||
// No external objects in simple benchmarks.
|
// No external objects in simple benchmarks.
|
||||||
static inline int gc_extern_space_visit(struct gc_extern_space *space,
|
static inline int gc_extern_space_visit(struct gc_extern_space *space,
|
||||||
struct gc_edge edge,
|
|
||||||
struct gc_ref ref) {
|
struct gc_ref ref) {
|
||||||
GC_CRASH();
|
GC_CRASH();
|
||||||
}
|
}
|
||||||
|
@ -93,24 +92,30 @@ static inline void gc_trace_heap_roots(struct gc_heap_roots *roots,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
gc_trace_mutator_conservative_roots(struct gc_mutator_roots *roots,
|
gc_trace_mutator_pinned_roots(struct gc_mutator_roots *roots,
|
||||||
void (*trace_range)(uintptr_t start,
|
void (*trace_pinned)(struct gc_ref ref,
|
||||||
uintptr_t end,
|
struct gc_heap *heap,
|
||||||
int possibly_interior,
|
void *data),
|
||||||
struct gc_heap *heap,
|
void (*trace_ambiguous)(uintptr_t start,
|
||||||
void *data),
|
uintptr_t end,
|
||||||
struct gc_heap *heap,
|
int possibly_interior,
|
||||||
void *data) {}
|
struct gc_heap *heap,
|
||||||
|
void *data),
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *data) {}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
gc_trace_heap_conservative_roots(struct gc_heap_roots *roots,
|
gc_trace_heap_pinned_roots(struct gc_heap_roots *roots,
|
||||||
void (*trace_range)(uintptr_t start,
|
void (*trace_pinned)(struct gc_ref ref,
|
||||||
uintptr_t end,
|
struct gc_heap *heap,
|
||||||
int possibly_interior,
|
void *data),
|
||||||
struct gc_heap *heap,
|
void (*trace_ambiguous)(uintptr_t start,
|
||||||
void *data),
|
uintptr_t end,
|
||||||
struct gc_heap *heap,
|
int possibly_interior,
|
||||||
void *data) {}
|
struct gc_heap *heap,
|
||||||
|
void *data),
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *data) {}
|
||||||
|
|
||||||
static inline uintptr_t gc_object_forwarded_nonatomic(struct gc_ref ref) {
|
static inline uintptr_t gc_object_forwarded_nonatomic(struct gc_ref ref) {
|
||||||
uintptr_t tag = *tag_word(ref);
|
uintptr_t tag = *tag_word(ref);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#define GC_IMPL 1
|
#define GC_IMPL 1
|
||||||
|
|
||||||
|
#include "gc-align.h"
|
||||||
#include "gc-api.h"
|
#include "gc-api.h"
|
||||||
#include "gc-ephemeron.h"
|
#include "gc-ephemeron.h"
|
||||||
#include "gc-tracepoint.h"
|
#include "gc-tracepoint.h"
|
||||||
|
@ -218,16 +219,20 @@ struct bdw_mark_state {
|
||||||
struct GC_ms_entry *mark_stack_limit;
|
struct GC_ms_entry *mark_stack_limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdw_mark_edge(struct gc_edge edge, struct gc_heap *heap,
|
static void bdw_mark(struct gc_ref ref, struct gc_heap *heap,
|
||||||
void *visit_data) {
|
void *visit_data) {
|
||||||
struct bdw_mark_state *state = visit_data;
|
struct bdw_mark_state *state = visit_data;
|
||||||
uintptr_t addr = gc_ref_value(gc_edge_ref(edge));
|
state->mark_stack_ptr = GC_MARK_AND_PUSH ((void *) gc_ref_value(ref),
|
||||||
state->mark_stack_ptr = GC_MARK_AND_PUSH ((void *) addr,
|
|
||||||
state->mark_stack_ptr,
|
state->mark_stack_ptr,
|
||||||
state->mark_stack_limit,
|
state->mark_stack_limit,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bdw_mark_edge(struct gc_edge edge, struct gc_heap *heap,
|
||||||
|
void *visit_data) {
|
||||||
|
bdw_mark(gc_edge_ref(edge), heap, visit_data);
|
||||||
|
}
|
||||||
|
|
||||||
static void bdw_mark_range(uintptr_t lo, uintptr_t hi, int possibly_interior,
|
static void bdw_mark_range(uintptr_t lo, uintptr_t hi, int possibly_interior,
|
||||||
struct gc_heap *heap, void *visit_data) {
|
struct gc_heap *heap, void *visit_data) {
|
||||||
struct bdw_mark_state *state = visit_data;
|
struct bdw_mark_state *state = visit_data;
|
||||||
|
@ -395,7 +400,8 @@ mark_heap(GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
|
||||||
return state.mark_stack_ptr;
|
return state.mark_stack_ptr;
|
||||||
|
|
||||||
if (heap->roots) {
|
if (heap->roots) {
|
||||||
gc_trace_heap_conservative_roots(heap->roots, bdw_mark_range, heap, &state);
|
gc_trace_heap_pinned_roots(heap->roots, bdw_mark, bdw_mark_range,
|
||||||
|
heap, &state);
|
||||||
gc_trace_heap_roots(heap->roots, bdw_mark_edge, heap, &state);
|
gc_trace_heap_roots(heap->roots, bdw_mark_edge, heap, &state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,8 +438,8 @@ mark_mutator(GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
|
||||||
memset(mut->freelists, 0, sizeof(void*) * GC_INLINE_FREELIST_COUNT);
|
memset(mut->freelists, 0, sizeof(void*) * GC_INLINE_FREELIST_COUNT);
|
||||||
|
|
||||||
if (mut->roots) {
|
if (mut->roots) {
|
||||||
gc_trace_mutator_conservative_roots(mut->roots, bdw_mark_range,
|
gc_trace_mutator_pinned_roots(mut->roots, bdw_mark, bdw_mark_range,
|
||||||
mut->heap, &state);
|
mut->heap, &state);
|
||||||
gc_trace_mutator_roots(mut->roots, bdw_mark_edge, mut->heap, &state);
|
gc_trace_mutator_roots(mut->roots, bdw_mark_edge, mut->heap, &state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,8 @@ static int visit_roots(struct dl_phdr_info *info, size_t size, void *data) {
|
||||||
if (p->p_type == PT_LOAD && (p->p_flags & PF_W)) {
|
if (p->p_type == PT_LOAD && (p->p_flags & PF_W)) {
|
||||||
uintptr_t start = p->p_vaddr + object_addr;
|
uintptr_t start = p->p_vaddr + object_addr;
|
||||||
uintptr_t end = start + p->p_memsz;
|
uintptr_t end = start + p->p_memsz;
|
||||||
|
start = align_up(start, sizeof(void*));
|
||||||
|
end = align_down(end, sizeof(void*));
|
||||||
DEBUG("found roots for '%s': [%p,%p)\n", object_name,
|
DEBUG("found roots for '%s': [%p,%p)\n", object_name,
|
||||||
(void*)start, (void*)end);
|
(void*)start, (void*)end);
|
||||||
visit_data->f(start, end, visit_data->heap, visit_data->data);
|
visit_data->f(start, end, visit_data->heap, visit_data->data);
|
||||||
|
|
|
@ -146,7 +146,7 @@ do_trace(struct gc_heap *heap, struct gc_edge edge, struct gc_ref ref,
|
||||||
else if (large_object_space_contains_with_lock(heap_large_object_space(heap), ref))
|
else if (large_object_space_contains_with_lock(heap_large_object_space(heap), ref))
|
||||||
return large_object_space_mark(heap_large_object_space(heap), ref);
|
return large_object_space_mark(heap_large_object_space(heap), ref);
|
||||||
else
|
else
|
||||||
return gc_extern_space_visit(heap_extern_space(heap), edge, ref);
|
return gc_extern_space_visit(heap_extern_space(heap), ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
@ -166,6 +166,34 @@ trace_edge(struct gc_heap *heap, struct gc_edge edge,
|
||||||
return is_new;
|
return is_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
do_trace_pinned(struct gc_heap *heap, struct gc_ref ref,
|
||||||
|
struct gc_trace_worker_data *data) {
|
||||||
|
if (GC_LIKELY(nofl_space_contains(heap_nofl_space(heap), ref)))
|
||||||
|
return nofl_space_mark_object(heap_nofl_space(heap), ref, &data->allocator);
|
||||||
|
else if (large_object_space_contains_with_lock(heap_large_object_space(heap),
|
||||||
|
ref))
|
||||||
|
return large_object_space_mark(heap_large_object_space(heap), ref);
|
||||||
|
else
|
||||||
|
return gc_extern_space_visit(heap_extern_space(heap), ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
trace_pinned_edge(struct gc_heap *heap, struct gc_ref ref,
|
||||||
|
struct gc_trace_worker_data *data) {
|
||||||
|
if (gc_ref_is_null(ref) || gc_ref_is_immediate(ref))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int is_new = do_trace_pinned(heap, ref, data);
|
||||||
|
|
||||||
|
if (is_new &&
|
||||||
|
GC_UNLIKELY(atomic_load_explicit(&heap->check_pending_ephemerons,
|
||||||
|
memory_order_relaxed)))
|
||||||
|
gc_resolve_pending_ephemerons(ref, heap);
|
||||||
|
|
||||||
|
return is_new;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
gc_visit_ephemeron_key(struct gc_edge edge, struct gc_heap *heap) {
|
gc_visit_ephemeron_key(struct gc_edge edge, struct gc_heap *heap) {
|
||||||
struct gc_ref ref = gc_edge_ref(edge);
|
struct gc_ref ref = gc_edge_ref(edge);
|
||||||
|
@ -274,6 +302,17 @@ tracer_visit(struct gc_edge edge, struct gc_heap *heap, void *trace_data) {
|
||||||
gc_trace_worker_enqueue(worker, gc_edge_ref(edge));
|
gc_trace_worker_enqueue(worker, gc_edge_ref(edge));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
tracer_visit_pinned_root(struct gc_ref ref, struct gc_heap *heap,
|
||||||
|
void *trace_data) GC_ALWAYS_INLINE;
|
||||||
|
static inline void
|
||||||
|
tracer_visit_pinned_root(struct gc_ref ref, struct gc_heap *heap,
|
||||||
|
void *trace_data) {
|
||||||
|
struct gc_trace_worker *worker = trace_data;
|
||||||
|
if (trace_pinned_edge(heap, ref, gc_trace_worker_data(worker)))
|
||||||
|
gc_trace_worker_enqueue(worker, ref);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
trace_remembered_edge(struct gc_edge edge, struct gc_heap *heap, void *trace_data) {
|
trace_remembered_edge(struct gc_edge edge, struct gc_heap *heap, void *trace_data) {
|
||||||
tracer_visit(edge, heap, trace_data);
|
tracer_visit(edge, heap, trace_data);
|
||||||
|
@ -331,8 +370,8 @@ static inline void
|
||||||
trace_conservative_edges(uintptr_t low, uintptr_t high, int possibly_interior,
|
trace_conservative_edges(uintptr_t low, uintptr_t high, int possibly_interior,
|
||||||
struct gc_heap *heap, void *data) {
|
struct gc_heap *heap, void *data) {
|
||||||
struct gc_trace_worker *worker = data;
|
struct gc_trace_worker *worker = data;
|
||||||
GC_ASSERT(low == align_down(low, sizeof(uintptr_t)));
|
GC_ASSERT_EQ(low, align_down(low, sizeof(uintptr_t)));
|
||||||
GC_ASSERT(high == align_down(high, sizeof(uintptr_t)));
|
GC_ASSERT_EQ(high, align_down(high, sizeof(uintptr_t)));
|
||||||
for (uintptr_t addr = low; addr < high; addr += sizeof(uintptr_t))
|
for (uintptr_t addr = low; addr < high; addr += sizeof(uintptr_t))
|
||||||
tracer_trace_conservative_ref(load_conservative_ref(addr), heap, worker,
|
tracer_trace_conservative_ref(load_conservative_ref(addr), heap, worker,
|
||||||
possibly_interior);
|
possibly_interior);
|
||||||
|
@ -404,13 +443,17 @@ trace_root(struct gc_root root, struct gc_heap *heap,
|
||||||
gc_field_set_visit_edge_buffer(&heap->remembered_set, root.edge_buffer,
|
gc_field_set_visit_edge_buffer(&heap->remembered_set, root.edge_buffer,
|
||||||
trace_remembered_edge, heap, worker);
|
trace_remembered_edge, heap, worker);
|
||||||
break;
|
break;
|
||||||
case GC_ROOT_KIND_HEAP_CONSERVATIVE_ROOTS:
|
case GC_ROOT_KIND_HEAP_PINNED_ROOTS:
|
||||||
gc_trace_heap_conservative_roots(root.heap->roots, trace_conservative_edges,
|
gc_trace_heap_pinned_roots(root.heap->roots,
|
||||||
heap, worker);
|
tracer_visit_pinned_root,
|
||||||
|
trace_conservative_edges,
|
||||||
|
heap, worker);
|
||||||
break;
|
break;
|
||||||
case GC_ROOT_KIND_MUTATOR_CONSERVATIVE_ROOTS:
|
case GC_ROOT_KIND_MUTATOR_PINNED_ROOTS:
|
||||||
gc_trace_mutator_conservative_roots(root.mutator->roots,
|
gc_trace_mutator_pinned_roots(root.mutator->roots,
|
||||||
trace_conservative_edges, heap, worker);
|
tracer_visit_pinned_root,
|
||||||
|
trace_conservative_edges,
|
||||||
|
heap, worker);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GC_CRASH();
|
GC_CRASH();
|
||||||
|
@ -671,7 +714,7 @@ enqueue_mutator_conservative_roots(struct gc_heap *heap) {
|
||||||
&possibly_interior);
|
&possibly_interior);
|
||||||
if (mut->roots)
|
if (mut->roots)
|
||||||
gc_tracer_add_root(&heap->tracer,
|
gc_tracer_add_root(&heap->tracer,
|
||||||
gc_root_mutator_conservative_roots(mut));
|
gc_root_mutator_pinned_roots(mut));
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -685,7 +728,7 @@ enqueue_global_conservative_roots(struct gc_heap *heap) {
|
||||||
gc_platform_visit_global_conservative_roots
|
gc_platform_visit_global_conservative_roots
|
||||||
(enqueue_conservative_roots, heap, &possibly_interior);
|
(enqueue_conservative_roots, heap, &possibly_interior);
|
||||||
if (heap->roots)
|
if (heap->roots)
|
||||||
gc_tracer_add_root(&heap->tracer, gc_root_heap_conservative_roots(heap));
|
gc_tracer_add_root(&heap->tracer, gc_root_heap_pinned_roots(heap));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -298,7 +298,9 @@ nofl_metadata_byte_for_addr(uintptr_t addr) {
|
||||||
|
|
||||||
static uint8_t*
|
static uint8_t*
|
||||||
nofl_metadata_byte_for_object(struct gc_ref ref) {
|
nofl_metadata_byte_for_object(struct gc_ref ref) {
|
||||||
return nofl_metadata_byte_for_addr(gc_ref_value(ref));
|
uint8_t *ret = nofl_metadata_byte_for_addr(gc_ref_value(ref));
|
||||||
|
GC_ASSERT(*ret & NOFL_METADATA_BYTE_MARK_MASK);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t*
|
static uint8_t*
|
||||||
|
@ -932,7 +934,7 @@ nofl_finish_sweeping(struct nofl_allocator *alloc,
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
nofl_is_ephemeron(struct gc_ref ref) {
|
nofl_is_ephemeron(struct gc_ref ref) {
|
||||||
uint8_t meta = *nofl_metadata_byte_for_addr(gc_ref_value(ref));
|
uint8_t meta = *nofl_metadata_byte_for_object(ref);
|
||||||
uint8_t kind = meta & NOFL_METADATA_BYTE_TRACE_KIND_MASK;
|
uint8_t kind = meta & NOFL_METADATA_BYTE_TRACE_KIND_MASK;
|
||||||
return kind == NOFL_METADATA_BYTE_TRACE_EPHEMERON;
|
return kind == NOFL_METADATA_BYTE_TRACE_EPHEMERON;
|
||||||
}
|
}
|
||||||
|
@ -940,7 +942,7 @@ nofl_is_ephemeron(struct gc_ref ref) {
|
||||||
static void
|
static void
|
||||||
nofl_space_set_ephemeron_flag(struct gc_ref ref) {
|
nofl_space_set_ephemeron_flag(struct gc_ref ref) {
|
||||||
if (gc_has_conservative_intraheap_edges()) {
|
if (gc_has_conservative_intraheap_edges()) {
|
||||||
uint8_t *metadata = nofl_metadata_byte_for_addr(gc_ref_value(ref));
|
uint8_t *metadata = nofl_metadata_byte_for_object(ref);
|
||||||
uint8_t byte = *metadata & ~NOFL_METADATA_BYTE_TRACE_KIND_MASK;
|
uint8_t byte = *metadata & ~NOFL_METADATA_BYTE_TRACE_KIND_MASK;
|
||||||
*metadata = byte | NOFL_METADATA_BYTE_TRACE_EPHEMERON;
|
*metadata = byte | NOFL_METADATA_BYTE_TRACE_EPHEMERON;
|
||||||
}
|
}
|
||||||
|
@ -1558,7 +1560,7 @@ nofl_space_evacuate(struct nofl_space *space, uint8_t *metadata, uint8_t byte,
|
||||||
gc_atomic_forward_commit(&fwd, new_ref);
|
gc_atomic_forward_commit(&fwd, new_ref);
|
||||||
// Now update extent metadata, and indicate to the caller that
|
// Now update extent metadata, and indicate to the caller that
|
||||||
// the object's fields need to be traced.
|
// the object's fields need to be traced.
|
||||||
uint8_t *new_metadata = nofl_metadata_byte_for_object(new_ref);
|
uint8_t *new_metadata = nofl_metadata_byte_for_addr(gc_ref_value(new_ref));
|
||||||
memcpy(new_metadata + 1, metadata + 1, object_granules - 1);
|
memcpy(new_metadata + 1, metadata + 1, object_granules - 1);
|
||||||
if (GC_GENERATIONAL)
|
if (GC_GENERATIONAL)
|
||||||
byte = clear_logged_bits_in_evacuated_object(byte, new_metadata,
|
byte = clear_logged_bits_in_evacuated_object(byte, new_metadata,
|
||||||
|
@ -1615,6 +1617,19 @@ nofl_space_evacuate_or_mark_object(struct nofl_space *space,
|
||||||
return nofl_space_set_nonempty_mark(space, metadata, byte, old_ref);
|
return nofl_space_set_nonempty_mark(space, metadata, byte, old_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
nofl_space_mark_object(struct nofl_space *space, struct gc_ref ref,
|
||||||
|
struct nofl_allocator *evacuate) {
|
||||||
|
uint8_t *metadata = nofl_metadata_byte_for_object(ref);
|
||||||
|
uint8_t byte = *metadata;
|
||||||
|
if (nofl_metadata_byte_has_mark(byte, space->current_mark))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
GC_ASSERT(!nofl_space_should_evacuate(space, byte, ref));
|
||||||
|
|
||||||
|
return nofl_space_set_nonempty_mark(space, metadata, byte, ref);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
nofl_space_forward_if_evacuated(struct nofl_space *space,
|
nofl_space_forward_if_evacuated(struct nofl_space *space,
|
||||||
struct gc_edge edge,
|
struct gc_edge edge,
|
||||||
|
@ -1719,6 +1734,7 @@ nofl_space_mark_conservative_ref(struct nofl_space *space,
|
||||||
addr = block_base + (loc - loc_base) * NOFL_GRANULE_SIZE;
|
addr = block_base + (loc - loc_base) * NOFL_GRANULE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GC_ASSERT(*loc & NOFL_METADATA_BYTE_MARK_MASK);
|
||||||
nofl_space_set_nonempty_mark(space, loc, byte, gc_ref(addr));
|
nofl_space_set_nonempty_mark(space, loc, byte, gc_ref(addr));
|
||||||
|
|
||||||
return gc_ref(addr);
|
return gc_ref(addr);
|
||||||
|
|
|
@ -422,7 +422,7 @@ static inline int do_trace(struct gc_heap *heap, struct gc_edge edge,
|
||||||
if (large_object_space_contains_with_lock(heap_large_object_space(heap), ref))
|
if (large_object_space_contains_with_lock(heap_large_object_space(heap), ref))
|
||||||
return large_object_space_mark(heap_large_object_space(heap), ref);
|
return large_object_space_mark(heap_large_object_space(heap), ref);
|
||||||
else
|
else
|
||||||
return gc_extern_space_visit(heap_extern_space(heap), edge, ref);
|
return gc_extern_space_visit(heap_extern_space(heap), ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int trace_edge(struct gc_heap *heap, struct gc_edge edge,
|
static inline int trace_edge(struct gc_heap *heap, struct gc_edge edge,
|
||||||
|
|
|
@ -18,8 +18,8 @@ enum gc_root_kind {
|
||||||
GC_ROOT_KIND_RESOLVED_EPHEMERONS,
|
GC_ROOT_KIND_RESOLVED_EPHEMERONS,
|
||||||
GC_ROOT_KIND_EDGE,
|
GC_ROOT_KIND_EDGE,
|
||||||
GC_ROOT_KIND_EDGE_BUFFER,
|
GC_ROOT_KIND_EDGE_BUFFER,
|
||||||
GC_ROOT_KIND_HEAP_CONSERVATIVE_ROOTS,
|
GC_ROOT_KIND_HEAP_PINNED_ROOTS,
|
||||||
GC_ROOT_KIND_MUTATOR_CONSERVATIVE_ROOTS,
|
GC_ROOT_KIND_MUTATOR_PINNED_ROOTS,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gc_root {
|
struct gc_root {
|
||||||
|
@ -81,15 +81,15 @@ gc_root_edge_buffer(struct gc_edge_buffer *buf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct gc_root
|
static inline struct gc_root
|
||||||
gc_root_heap_conservative_roots(struct gc_heap* heap) {
|
gc_root_heap_pinned_roots(struct gc_heap* heap) {
|
||||||
struct gc_root ret = { GC_ROOT_KIND_HEAP_CONSERVATIVE_ROOTS };
|
struct gc_root ret = { GC_ROOT_KIND_HEAP_PINNED_ROOTS };
|
||||||
ret.heap = heap;
|
ret.heap = heap;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct gc_root
|
static inline struct gc_root
|
||||||
gc_root_mutator_conservative_roots(struct gc_mutator* mutator) {
|
gc_root_mutator_pinned_roots(struct gc_mutator* mutator) {
|
||||||
struct gc_root ret = { GC_ROOT_KIND_MUTATOR_CONSERVATIVE_ROOTS };
|
struct gc_root ret = { GC_ROOT_KIND_MUTATOR_PINNED_ROOTS };
|
||||||
ret.mutator = mutator;
|
ret.mutator = mutator;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,13 +236,12 @@ static int semi_space_contains(struct semi_space *space, struct gc_ref ref) {
|
||||||
|
|
||||||
static void visit_external_object(struct gc_heap *heap,
|
static void visit_external_object(struct gc_heap *heap,
|
||||||
struct gc_extern_space *space,
|
struct gc_extern_space *space,
|
||||||
struct gc_edge edge,
|
struct gc_ref ref) {
|
||||||
struct gc_ref old_ref) {
|
if (gc_extern_space_visit(space, ref)) {
|
||||||
if (gc_extern_space_visit(space, edge, old_ref)) {
|
|
||||||
if (GC_UNLIKELY(heap->check_pending_ephemerons))
|
if (GC_UNLIKELY(heap->check_pending_ephemerons))
|
||||||
gc_resolve_pending_ephemerons(old_ref, heap);
|
gc_resolve_pending_ephemerons(ref, heap);
|
||||||
|
|
||||||
gc_trace_object(gc_edge_ref(edge), trace, heap, NULL, NULL);
|
gc_trace_object(ref, trace, heap, NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +255,7 @@ static void visit(struct gc_edge edge, struct gc_heap *heap) {
|
||||||
ref))
|
ref))
|
||||||
visit_large_object_space(heap, heap_large_object_space(heap), ref);
|
visit_large_object_space(heap, heap_large_object_space(heap), ref);
|
||||||
else
|
else
|
||||||
visit_external_object(heap, heap->extern_space, edge, ref);
|
visit_external_object(heap, heap->extern_space, ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gc_pending_ephemerons *
|
struct gc_pending_ephemerons *
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue