mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 04:10:18 +02:00
Switch to use Whippet allocation fast paths
* libguile/Makefile.am (noinst_HEADERS, modinclude_HEADERS): Move gc-inline.h to be a private header. * libguile/gc-inline.h (scm_inline_gc_malloc_pointerless): (scm_inline_gc_malloc): Use gc_allocate. * libguile/intrinsics.c (allocate_words_with_freelist): (allocate_pointerless_words_with_freelist): Remove these intrinsics. Renumbers the intrinsics. (scm_bootstrap_intrinsics): * libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Adapt to intrinsics change. * libguile/jit.c (emit_update_alloc_table): (emit_allocate_bytes_fast_freelist): (emit_allocate_words_slow): New helpers. (compile_allocate_words): (compile_allocate_words_immediate): (compile_allocate_words_immediate_slow): (compile_allocate_pointerless_words): (compile_allocate_pointerless_words_immediate): (compile_allocate_pointerless_words_immediate_slow): Use new helpers. * libguile/threads.c (scm_trace_thread_mutator_roots): (on_thread_exit): * libguile/threads.h: Remove Guile-managed thread-local freelists.
This commit is contained in:
parent
7696344634
commit
0532602cd3
7 changed files with 93 additions and 185 deletions
171
libguile/jit.c
171
libguile/jit.c
|
@ -2285,18 +2285,60 @@ compile_bind_optionals_slow (scm_jit_state *j, uint32_t nlocals)
|
|||
{
|
||||
}
|
||||
|
||||
static void
|
||||
emit_update_alloc_table(scm_jit_state *j, jit_gpr_t obj, size_t size,
|
||||
enum gc_allocation_kind kind)
|
||||
{
|
||||
size_t alignment = gc_allocator_alloc_table_alignment();
|
||||
if (!alignment) return;
|
||||
DIE ("allocation table unimplemented");
|
||||
}
|
||||
|
||||
static inline void
|
||||
emit_allocate_bytes_fast_freelist (scm_jit_state *j, jit_gpr_t dst, size_t bytes,
|
||||
enum gc_allocation_kind kind,
|
||||
jit_gpr_t tmp1, jit_gpr_t tmp2)
|
||||
{
|
||||
jit_gpr_t mut = tmp1;
|
||||
emit_ldxi (j, mut, THREAD, offsetof(struct scm_thread, mutator));
|
||||
size_t offset = gc_allocator_freelist_offset (bytes, kind);
|
||||
emit_ldxi (j, dst, mut, offset);
|
||||
add_slow_path_patch (j, jit_beqi (j->jit, dst, 0));
|
||||
jit_gpr_t new_freelist = tmp2;
|
||||
emit_ldr (j, new_freelist, dst);
|
||||
jit_stxi (j->jit, offset, mut, new_freelist);
|
||||
emit_update_alloc_table(j, dst, bytes, kind);
|
||||
}
|
||||
|
||||
static inline void
|
||||
emit_allocate_words_slow (scm_jit_state *j, jit_gpr_t res, jit_operand_t nwords,
|
||||
enum gc_allocation_kind kind)
|
||||
{
|
||||
emit_store_current_ip (j, res);
|
||||
SCM (*intrinsic)(struct scm_thread *, size_t);
|
||||
switch (kind)
|
||||
{
|
||||
case GC_ALLOCATION_TAGGED:
|
||||
intrinsic = scm_vm_intrinsics.allocate_words;
|
||||
break;
|
||||
case GC_ALLOCATION_UNTAGGED_POINTERLESS:
|
||||
intrinsic = scm_vm_intrinsics.allocate_pointerless_words;
|
||||
break;
|
||||
default:
|
||||
DIE ("unknown allocation kind");
|
||||
}
|
||||
|
||||
emit_call_2 (j, intrinsic, thread_operand(), nwords);
|
||||
emit_retval (j, res);
|
||||
emit_reload_sp (j);
|
||||
}
|
||||
|
||||
static void
|
||||
compile_allocate_words (scm_jit_state *j, uint32_t dst, uint32_t nwords)
|
||||
{
|
||||
jit_gpr_t t = T0;
|
||||
|
||||
emit_store_current_ip (j, t);
|
||||
emit_call_2 (j, scm_vm_intrinsics.allocate_words, thread_operand (),
|
||||
sp_sz_operand (j, nwords));
|
||||
emit_retval (j, t);
|
||||
record_gpr_clobber (j, t);
|
||||
emit_reload_sp (j);
|
||||
emit_sp_set_scm (j, dst, t);
|
||||
emit_allocate_words_slow (j, T0, sp_sz_operand (j, nwords),
|
||||
GC_ALLOCATION_TAGGED);
|
||||
emit_sp_set_scm (j, dst, T0);
|
||||
}
|
||||
static void
|
||||
compile_allocate_words_slow (scm_jit_state *j, uint32_t dst, uint32_t nwords)
|
||||
|
@ -2307,49 +2349,30 @@ static void
|
|||
compile_allocate_words_immediate (scm_jit_state *j, uint32_t dst, uint32_t nwords)
|
||||
{
|
||||
size_t bytes = nwords * sizeof(SCM);
|
||||
size_t idx = scm_inline_gc_bytes_to_freelist_index (bytes);
|
||||
|
||||
if (SCM_UNLIKELY (idx >= SCM_INLINE_GC_FREELIST_COUNT))
|
||||
{
|
||||
jit_gpr_t t = T0;
|
||||
emit_store_current_ip (j, t);
|
||||
emit_call_1 (j, GC_malloc, jit_operand_imm (JIT_OPERAND_ABI_WORD, bytes));
|
||||
emit_retval (j, t);
|
||||
emit_reload_sp (j);
|
||||
emit_sp_set_scm (j, dst, t);
|
||||
}
|
||||
if (gc_allocator_kind() == GC_ALLOCATOR_INLINE_FREELIST &&
|
||||
bytes <= gc_allocator_large_threshold ())
|
||||
emit_allocate_bytes_fast_freelist (j, T0, bytes, GC_ALLOCATION_TAGGED,
|
||||
T1, T2);
|
||||
else
|
||||
{
|
||||
jit_gpr_t res = T0;
|
||||
ptrdiff_t offset = offsetof(struct scm_thread, freelists);
|
||||
offset += idx * sizeof(void*);
|
||||
emit_ldxi (j, res, THREAD, offset);
|
||||
add_slow_path_patch (j, jit_beqi (j->jit, res, 0));
|
||||
jit_gpr_t new_freelist = T1;
|
||||
emit_ldr (j, new_freelist, res);
|
||||
jit_stxi (j->jit, offset, THREAD, new_freelist);
|
||||
emit_sp_set_scm (j, dst, res);
|
||||
}
|
||||
emit_allocate_words_slow (j, T0,
|
||||
jit_operand_imm (JIT_OPERAND_ABI_WORD, nwords),
|
||||
GC_ALLOCATION_TAGGED);
|
||||
emit_sp_set_scm (j, dst, T0);
|
||||
}
|
||||
static void
|
||||
compile_allocate_words_immediate_slow (scm_jit_state *j, uint32_t dst, uint32_t nwords)
|
||||
{
|
||||
size_t bytes = nwords * sizeof(SCM);
|
||||
size_t idx = scm_inline_gc_bytes_to_freelist_index (bytes);
|
||||
|
||||
if (SCM_UNLIKELY (idx >= SCM_INLINE_GC_FREELIST_COUNT))
|
||||
/* Only emit a slow path if there is a fast path. */
|
||||
if (gc_allocator_kind() == GC_ALLOCATOR_INLINE_FREELIST &&
|
||||
bytes <= gc_allocator_large_threshold ())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
jit_gpr_t res = T0;
|
||||
emit_store_current_ip (j, res);
|
||||
emit_call_2 (j, scm_vm_intrinsics.allocate_words_with_freelist,
|
||||
thread_operand (),
|
||||
jit_operand_imm (JIT_OPERAND_ABI_WORD, idx));
|
||||
emit_retval (j, res);
|
||||
emit_reload_sp (j);
|
||||
emit_sp_set_scm (j, dst, res);
|
||||
emit_allocate_words_slow (j, T0,
|
||||
jit_operand_imm (JIT_OPERAND_ABI_WORD, nwords),
|
||||
GC_ALLOCATION_TAGGED);
|
||||
emit_sp_set_scm (j, dst, T0);
|
||||
continue_after_slow_path (j, j->next_ip);
|
||||
}
|
||||
}
|
||||
|
@ -2357,15 +2380,9 @@ compile_allocate_words_immediate_slow (scm_jit_state *j, uint32_t dst, uint32_t
|
|||
static void
|
||||
compile_allocate_pointerless_words (scm_jit_state *j, uint32_t dst, uint32_t nwords)
|
||||
{
|
||||
jit_gpr_t t = T0;
|
||||
|
||||
emit_store_current_ip (j, t);
|
||||
emit_call_2 (j, scm_vm_intrinsics.allocate_pointerless_words, thread_operand (),
|
||||
sp_sz_operand (j, nwords));
|
||||
emit_retval (j, t);
|
||||
record_gpr_clobber (j, t);
|
||||
emit_reload_sp (j);
|
||||
emit_sp_set_scm (j, dst, t);
|
||||
emit_allocate_words_slow (j, T0, sp_sz_operand (j, nwords),
|
||||
GC_ALLOCATION_UNTAGGED_POINTERLESS);
|
||||
emit_sp_set_scm (j, dst, T0);
|
||||
}
|
||||
static void
|
||||
compile_allocate_pointerless_words_slow (scm_jit_state *j, uint32_t dst, uint32_t nwords)
|
||||
|
@ -2376,49 +2393,31 @@ static void
|
|||
compile_allocate_pointerless_words_immediate (scm_jit_state *j, uint32_t dst, uint32_t nwords)
|
||||
{
|
||||
size_t bytes = nwords * sizeof(SCM);
|
||||
size_t idx = scm_inline_gc_bytes_to_freelist_index (bytes);
|
||||
|
||||
if (SCM_UNLIKELY (idx >= SCM_INLINE_GC_FREELIST_COUNT))
|
||||
{
|
||||
jit_gpr_t t = T0;
|
||||
emit_store_current_ip (j, t);
|
||||
emit_call_1 (j, GC_malloc_atomic, jit_operand_imm (JIT_OPERAND_ABI_WORD, bytes));
|
||||
emit_retval (j, t);
|
||||
emit_reload_sp (j);
|
||||
emit_sp_set_scm (j, dst, t);
|
||||
}
|
||||
if (gc_allocator_kind() == GC_ALLOCATOR_INLINE_FREELIST &&
|
||||
bytes <= gc_allocator_large_threshold ())
|
||||
emit_allocate_bytes_fast_freelist (j, T0, bytes,
|
||||
GC_ALLOCATION_UNTAGGED_POINTERLESS,
|
||||
T1, T2);
|
||||
else
|
||||
{
|
||||
jit_gpr_t res = T0;
|
||||
ptrdiff_t offset = offsetof(struct scm_thread, pointerless_freelists);
|
||||
offset += idx * sizeof(void*);
|
||||
emit_ldxi (j, res, THREAD, offset);
|
||||
add_slow_path_patch (j, jit_beqi (j->jit, res, 0));
|
||||
jit_gpr_t new_freelist = T1;
|
||||
emit_ldr (j, new_freelist, res);
|
||||
jit_stxi (j->jit, offset, THREAD, new_freelist);
|
||||
emit_sp_set_scm (j, dst, res);
|
||||
}
|
||||
emit_allocate_words_slow (j, T0,
|
||||
jit_operand_imm (JIT_OPERAND_ABI_WORD, nwords),
|
||||
GC_ALLOCATION_UNTAGGED_POINTERLESS);
|
||||
emit_sp_set_scm (j, dst, T0);
|
||||
}
|
||||
static void
|
||||
compile_allocate_pointerless_words_immediate_slow (scm_jit_state *j, uint32_t dst, uint32_t nwords)
|
||||
{
|
||||
size_t bytes = nwords * sizeof(SCM);
|
||||
size_t idx = scm_inline_gc_bytes_to_freelist_index (bytes);
|
||||
|
||||
if (SCM_UNLIKELY (idx >= SCM_INLINE_GC_FREELIST_COUNT))
|
||||
/* Only emit a slow path if there is a fast path. */
|
||||
if (gc_allocator_kind() == GC_ALLOCATOR_INLINE_FREELIST &&
|
||||
bytes <= gc_allocator_large_threshold ())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
jit_gpr_t res = T0;
|
||||
emit_store_current_ip (j, res);
|
||||
emit_call_2 (j, scm_vm_intrinsics.allocate_pointerless_words_with_freelist,
|
||||
thread_operand (),
|
||||
jit_operand_imm (JIT_OPERAND_ABI_WORD, idx));
|
||||
emit_retval (j, res);
|
||||
emit_reload_sp (j);
|
||||
emit_sp_set_scm (j, dst, res);
|
||||
emit_allocate_words_slow (j, T0,
|
||||
jit_operand_imm (JIT_OPERAND_ABI_WORD, nwords),
|
||||
GC_ALLOCATION_UNTAGGED_POINTERLESS);
|
||||
emit_sp_set_scm (j, dst, T0);
|
||||
continue_after_slow_path (j, j->next_ip);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue