mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 04:10:18 +02:00
nofl: Refactor to trace visitor
This commit is contained in:
parent
7db72e7f80
commit
010185f729
1 changed files with 105 additions and 82 deletions
|
@ -1187,20 +1187,27 @@ nofl_space_sweep_until_memory_released(struct nofl_space *space,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
nofl_space_evacuate_or_mark_object(struct nofl_space *space,
|
nofl_space_should_evacuate(struct nofl_space *space, struct gc_ref obj) {
|
||||||
|
if (!space->evacuating)
|
||||||
|
return 0;
|
||||||
|
struct nofl_block_summary *summary =
|
||||||
|
nofl_block_summary_for_addr(gc_ref_value(obj));
|
||||||
|
return nofl_block_summary_has_flag(summary, NOFL_BLOCK_EVACUATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
nofl_space_set_mark(struct nofl_space *space, uint8_t *metadata, uint8_t byte) {
|
||||||
|
uint8_t mask = NOFL_METADATA_BYTE_YOUNG | NOFL_METADATA_BYTE_MARK_0
|
||||||
|
| NOFL_METADATA_BYTE_MARK_1 | NOFL_METADATA_BYTE_MARK_2;
|
||||||
|
*metadata = (byte & ~mask) | space->marked_mask;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
nofl_space_evacuate(struct nofl_space *space, uint8_t *metadata, uint8_t byte,
|
||||||
struct gc_edge edge,
|
struct gc_edge edge,
|
||||||
struct gc_ref old_ref,
|
struct gc_ref old_ref,
|
||||||
struct nofl_allocator *evacuate) {
|
struct nofl_allocator *evacuate) {
|
||||||
uint8_t *metadata = nofl_metadata_byte_for_object(old_ref);
|
|
||||||
uint8_t byte = *metadata;
|
|
||||||
if (byte & space->marked_mask)
|
|
||||||
return 0;
|
|
||||||
if (space->evacuating &&
|
|
||||||
nofl_block_summary_has_flag(nofl_block_summary_for_addr(gc_ref_value(old_ref)),
|
|
||||||
NOFL_BLOCK_EVACUATE)) {
|
|
||||||
// This is an evacuating collection, and we are attempting to
|
|
||||||
// evacuate this block, and we are tracing this particular object
|
|
||||||
// for what appears to be the first time.
|
|
||||||
struct gc_atomic_forward fwd = gc_atomic_forward_begin(old_ref);
|
struct gc_atomic_forward fwd = gc_atomic_forward_begin(old_ref);
|
||||||
|
|
||||||
if (fwd.state == GC_FORWARDING_STATE_NOT_FORWARDED)
|
if (fwd.state == GC_FORWARDING_STATE_NOT_FORWARDED)
|
||||||
|
@ -1209,6 +1216,7 @@ nofl_space_evacuate_or_mark_object(struct nofl_space *space,
|
||||||
switch (fwd.state) {
|
switch (fwd.state) {
|
||||||
case GC_FORWARDING_STATE_NOT_FORWARDED:
|
case GC_FORWARDING_STATE_NOT_FORWARDED:
|
||||||
case GC_FORWARDING_STATE_ABORTED:
|
case GC_FORWARDING_STATE_ABORTED:
|
||||||
|
default:
|
||||||
// Impossible.
|
// Impossible.
|
||||||
GC_CRASH();
|
GC_CRASH();
|
||||||
case GC_FORWARDING_STATE_ACQUIRED: {
|
case GC_FORWARDING_STATE_ACQUIRED: {
|
||||||
|
@ -1228,13 +1236,13 @@ nofl_space_evacuate_or_mark_object(struct nofl_space *space,
|
||||||
uint8_t *new_metadata = nofl_metadata_byte_for_object(new_ref);
|
uint8_t *new_metadata = nofl_metadata_byte_for_object(new_ref);
|
||||||
memcpy(new_metadata + 1, metadata + 1, object_granules - 1);
|
memcpy(new_metadata + 1, metadata + 1, object_granules - 1);
|
||||||
gc_edge_update(edge, new_ref);
|
gc_edge_update(edge, new_ref);
|
||||||
metadata = new_metadata;
|
return nofl_space_set_mark(space, new_metadata, byte);
|
||||||
// Fall through to set mark bits.
|
|
||||||
} else {
|
} else {
|
||||||
// Well shucks; allocation failed, marking the end of
|
// Well shucks; allocation failed, marking the end of
|
||||||
// opportunistic evacuation. No future evacuation of this
|
// opportunistic evacuation. No future evacuation of this
|
||||||
// object will succeed. Mark in place instead.
|
// object will succeed. Mark in place instead.
|
||||||
gc_atomic_forward_abort(&fwd);
|
gc_atomic_forward_abort(&fwd);
|
||||||
|
return nofl_space_set_mark(space, metadata, byte);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1260,10 +1268,21 @@ nofl_space_evacuate_or_mark_object(struct nofl_space *space,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t mask = NOFL_METADATA_BYTE_YOUNG | NOFL_METADATA_BYTE_MARK_0
|
static inline int
|
||||||
| NOFL_METADATA_BYTE_MARK_1 | NOFL_METADATA_BYTE_MARK_2;
|
nofl_space_evacuate_or_mark_object(struct nofl_space *space,
|
||||||
*metadata = (byte & ~mask) | space->marked_mask;
|
struct gc_edge edge,
|
||||||
return 1;
|
struct gc_ref old_ref,
|
||||||
|
struct nofl_allocator *evacuate) {
|
||||||
|
uint8_t *metadata = nofl_metadata_byte_for_object(old_ref);
|
||||||
|
uint8_t byte = *metadata;
|
||||||
|
if (byte & space->marked_mask)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (nofl_space_should_evacuate(space, old_ref))
|
||||||
|
return nofl_space_evacuate(space, metadata, byte, edge, old_ref,
|
||||||
|
evacuate);
|
||||||
|
|
||||||
|
return nofl_space_set_mark(space, metadata, byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
@ -1282,21 +1301,10 @@ nofl_space_contains(struct nofl_space *space, struct gc_ref ref) {
|
||||||
return nofl_space_contains_address(space, gc_ref_value(ref));
|
return nofl_space_contains_address(space, gc_ref_value(ref));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static inline int
|
||||||
nofl_space_forward_or_mark_if_traced(struct nofl_space *space,
|
nofl_space_forward_if_evacuated(struct nofl_space *space,
|
||||||
struct gc_edge edge,
|
struct gc_edge edge,
|
||||||
struct gc_ref ref) {
|
struct gc_ref ref) {
|
||||||
uint8_t *metadata = nofl_metadata_byte_for_object(ref);
|
|
||||||
uint8_t byte = *metadata;
|
|
||||||
if (byte & space->marked_mask)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (!space->evacuating)
|
|
||||||
return 0;
|
|
||||||
if (!nofl_block_summary_has_flag(nofl_block_summary_for_addr(gc_ref_value(ref)),
|
|
||||||
NOFL_BLOCK_EVACUATE))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
struct gc_atomic_forward fwd = gc_atomic_forward_begin(ref);
|
struct gc_atomic_forward fwd = gc_atomic_forward_begin(ref);
|
||||||
switch (fwd.state) {
|
switch (fwd.state) {
|
||||||
case GC_FORWARDING_STATE_NOT_FORWARDED:
|
case GC_FORWARDING_STATE_NOT_FORWARDED:
|
||||||
|
@ -1322,6 +1330,21 @@ nofl_space_forward_or_mark_if_traced(struct nofl_space *space,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nofl_space_forward_or_mark_if_traced(struct nofl_space *space,
|
||||||
|
struct gc_edge edge,
|
||||||
|
struct gc_ref ref) {
|
||||||
|
uint8_t *metadata = nofl_metadata_byte_for_object(ref);
|
||||||
|
uint8_t byte = *metadata;
|
||||||
|
if (byte & space->marked_mask)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!nofl_space_should_evacuate(space, ref))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return nofl_space_forward_if_evacuated(space, edge, ref);
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct gc_ref
|
static inline struct gc_ref
|
||||||
nofl_space_mark_conservative_ref(struct nofl_space *space,
|
nofl_space_mark_conservative_ref(struct nofl_space *space,
|
||||||
struct gc_conservative_ref ref,
|
struct gc_conservative_ref ref,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue