mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-28 07:50:20 +02:00
Rework write barrier fast/slow paths
This commit is contained in:
parent
1ecb45a437
commit
095515eaed
1 changed files with 21 additions and 14 deletions
35
api/gc-api.h
35
api/gc-api.h
|
@ -210,15 +210,15 @@ GC_API_ void gc_write_barrier_slow(struct gc_mutator *mut, struct gc_ref obj,
|
||||||
size_t obj_size, struct gc_edge edge,
|
size_t obj_size, struct gc_edge edge,
|
||||||
struct gc_ref new_val) GC_NEVER_INLINE;
|
struct gc_ref new_val) GC_NEVER_INLINE;
|
||||||
|
|
||||||
static inline void gc_write_barrier(struct gc_mutator *mut, struct gc_ref obj,
|
static inline int gc_write_barrier_fast(struct gc_mutator *mut, struct gc_ref obj,
|
||||||
size_t obj_size, struct gc_edge edge,
|
size_t obj_size, struct gc_edge edge,
|
||||||
struct gc_ref new_val) GC_ALWAYS_INLINE;
|
struct gc_ref new_val) GC_ALWAYS_INLINE;
|
||||||
static inline void gc_write_barrier(struct gc_mutator *mut, struct gc_ref obj,
|
static inline int gc_write_barrier_fast(struct gc_mutator *mut, struct gc_ref obj,
|
||||||
size_t obj_size, struct gc_edge edge,
|
size_t obj_size, struct gc_edge edge,
|
||||||
struct gc_ref new_val) {
|
struct gc_ref new_val) {
|
||||||
switch (gc_write_barrier_kind(obj_size)) {
|
switch (gc_write_barrier_kind(obj_size)) {
|
||||||
case GC_WRITE_BARRIER_NONE:
|
case GC_WRITE_BARRIER_NONE:
|
||||||
return;
|
return 0;
|
||||||
case GC_WRITE_BARRIER_CARD: {
|
case GC_WRITE_BARRIER_CARD: {
|
||||||
size_t card_table_alignment = gc_write_barrier_card_table_alignment();
|
size_t card_table_alignment = gc_write_barrier_card_table_alignment();
|
||||||
size_t card_size = gc_write_barrier_card_size();
|
size_t card_size = gc_write_barrier_card_size();
|
||||||
|
@ -226,11 +226,11 @@ static inline void gc_write_barrier(struct gc_mutator *mut, struct gc_ref obj,
|
||||||
uintptr_t base = addr & ~(card_table_alignment - 1);
|
uintptr_t base = addr & ~(card_table_alignment - 1);
|
||||||
uintptr_t card = (addr & (card_table_alignment - 1)) / card_size;
|
uintptr_t card = (addr & (card_table_alignment - 1)) / card_size;
|
||||||
atomic_store_explicit((uint8_t*)(base + card), 1, memory_order_relaxed);
|
atomic_store_explicit((uint8_t*)(base + card), 1, memory_order_relaxed);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
case GC_WRITE_BARRIER_FIELD: {
|
case GC_WRITE_BARRIER_FIELD: {
|
||||||
if (!gc_object_is_old_generation(mut, obj, obj_size))
|
if (!gc_object_is_old_generation(mut, obj, obj_size))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
size_t field_table_alignment = gc_write_barrier_field_table_alignment();
|
size_t field_table_alignment = gc_write_barrier_field_table_alignment();
|
||||||
size_t fields_per_byte = gc_write_barrier_field_fields_per_byte();
|
size_t fields_per_byte = gc_write_barrier_field_fields_per_byte();
|
||||||
|
@ -243,18 +243,25 @@ static inline void gc_write_barrier(struct gc_mutator *mut, struct gc_ref obj,
|
||||||
uint8_t log_bit = first_bit_pattern << (field % fields_per_byte);
|
uint8_t log_bit = first_bit_pattern << (field % fields_per_byte);
|
||||||
uint8_t *byte_loc = (uint8_t*)(base + log_byte);
|
uint8_t *byte_loc = (uint8_t*)(base + log_byte);
|
||||||
uint8_t byte = atomic_load_explicit(byte_loc, memory_order_relaxed);
|
uint8_t byte = atomic_load_explicit(byte_loc, memory_order_relaxed);
|
||||||
if (!(byte & log_bit))
|
return byte & log_bit;
|
||||||
gc_write_barrier_slow(mut, obj, obj_size, edge, new_val);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
case GC_WRITE_BARRIER_SLOW:
|
case GC_WRITE_BARRIER_SLOW:
|
||||||
gc_write_barrier_slow(mut, obj, obj_size, edge, new_val);
|
return 1;
|
||||||
return;
|
|
||||||
default:
|
default:
|
||||||
GC_CRASH();
|
GC_CRASH();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void gc_write_barrier(struct gc_mutator *mut, struct gc_ref obj,
|
||||||
|
size_t obj_size, struct gc_edge edge,
|
||||||
|
struct gc_ref new_val) GC_ALWAYS_INLINE;
|
||||||
|
static inline void gc_write_barrier(struct gc_mutator *mut, struct gc_ref obj,
|
||||||
|
size_t obj_size, struct gc_edge edge,
|
||||||
|
struct gc_ref new_val) {
|
||||||
|
if (GC_UNLIKELY(gc_write_barrier_fast(mut, obj, obj_size, edge, new_val)))
|
||||||
|
gc_write_barrier_slow(mut, obj, obj_size, edge, new_val);
|
||||||
|
}
|
||||||
|
|
||||||
GC_API_ void gc_pin_object(struct gc_mutator *mut, struct gc_ref obj);
|
GC_API_ void gc_pin_object(struct gc_mutator *mut, struct gc_ref obj);
|
||||||
|
|
||||||
GC_API_ void gc_safepoint_slow(struct gc_mutator *mut) GC_NEVER_INLINE;
|
GC_API_ void gc_safepoint_slow(struct gc_mutator *mut) GC_NEVER_INLINE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue