mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 20:00:19 +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
|
||||
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_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 (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);
|
||||
|
||||
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) {
|
||||
case GC_FORWARDING_STATE_NOT_FORWARDED:
|
||||
case GC_FORWARDING_STATE_ABORTED:
|
||||
default:
|
||||
// Impossible.
|
||||
GC_CRASH();
|
||||
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);
|
||||
memcpy(new_metadata + 1, metadata + 1, object_granules - 1);
|
||||
gc_edge_update(edge, new_ref);
|
||||
metadata = new_metadata;
|
||||
// Fall through to set mark bits.
|
||||
return nofl_space_set_mark(space, new_metadata, byte);
|
||||
} else {
|
||||
// Well shucks; allocation failed, marking the end of
|
||||
// opportunistic evacuation. No future evacuation of this
|
||||
// object will succeed. Mark in place instead.
|
||||
gc_atomic_forward_abort(&fwd);
|
||||
return nofl_space_set_mark(space, metadata, byte);
|
||||
}
|
||||
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
|
||||
| NOFL_METADATA_BYTE_MARK_1 | NOFL_METADATA_BYTE_MARK_2;
|
||||
*metadata = (byte & ~mask) | space->marked_mask;
|
||||
return 1;
|
||||
static inline int
|
||||
nofl_space_evacuate_or_mark_object(struct nofl_space *space,
|
||||
struct gc_edge edge,
|
||||
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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
static int
|
||||
nofl_space_forward_or_mark_if_traced(struct nofl_space *space,
|
||||
static inline int
|
||||
nofl_space_forward_if_evacuated(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 (!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);
|
||||
switch (fwd.state) {
|
||||
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
|
||||
nofl_space_mark_conservative_ref(struct nofl_space *space,
|
||||
struct gc_conservative_ref ref,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue