Skip to content

Commit f574d98

Browse files
committed
Implement allocation fast path for Immix
This commit implements a fast path that inlines mmtk_post_alloc for Immix. The benchmark results show a decent speed up in allocation performance. GC.disable i = 0 while i < 10_000_000 Object.new i += 1 end Before: Time (mean ± σ): 506.3 ms ± 5.0 ms [User: 442.8 ms, System: 108.8 ms] Range (min … max): 497.8 ms … 513.2 ms 10 runs After: Time (mean ± σ): 473.9 ms ± 2.4 ms [User: 409.4 ms, System: 108.8 ms] Range (min … max): 470.4 ms … 478.1 ms 10 runs
1 parent d764343 commit f574d98

3 files changed

Lines changed: 39 additions & 2 deletions

File tree

gc/mmtk/mmtk.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ struct objspace {
4949
struct rb_gc_vm_context vm_context;
5050

5151
unsigned int fork_hook_vm_lock_lev;
52+
53+
uintptr_t vo_bit_log_region_size;
54+
uintptr_t vo_bit_base_addr;
5255
};
5356

5457
#define OBJ_FREE_BUF_CAPACITY 128
@@ -591,6 +594,9 @@ rb_gc_impl_objspace_init(void *objspace_ptr)
591594
objspace->cond_world_started = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
592595

593596
objspace->event_hook_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
597+
598+
objspace->vo_bit_log_region_size = mmtk_get_vo_bit_log_region_size();
599+
objspace->vo_bit_base_addr = mmtk_get_vo_bit_base_addr();
594600
}
595601

596602
void
@@ -883,6 +889,18 @@ mmtk_buffer_obj_free_candidate(struct MMTk_ractor_cache *cache, VALUE obj)
883889
}
884890
}
885891

892+
static void
893+
mmtk_post_alloc_fast_immix(struct objspace *objspace, struct MMTk_ractor_cache *ractor_cache, uintptr_t obj)
894+
{
895+
uintptr_t region_offset = obj >> objspace->vo_bit_log_region_size;
896+
uintptr_t byte_offset = region_offset / 8;
897+
uintptr_t bit_offset = region_offset % 8;
898+
uintptr_t meta_byte_address = objspace->vo_bit_base_addr + byte_offset;
899+
uint8_t byte = 1 << bit_offset;
900+
uint8_t *meta_byte_ptr = (uint8_t*)meta_byte_address;
901+
*meta_byte_ptr |= byte;
902+
}
903+
886904
VALUE
887905
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size)
888906
{
@@ -916,8 +934,13 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
916934
alloc_obj[0] = flags;
917935
alloc_obj[1] = klass;
918936

919-
// TODO: implement fast path for mmtk_post_alloc
920-
mmtk_post_alloc(ractor_cache->mutator, (void*)alloc_obj, alloc_size, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
937+
if (ractor_cache->bump_pointer == NULL) {
938+
mmtk_post_alloc(ractor_cache->mutator, (void*)alloc_obj, alloc_size, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
939+
}
940+
else {
941+
// We can use the post alloc fast path if we're using Immix bump pointer allocator
942+
mmtk_post_alloc_fast_immix(objspace, ractor_cache, (uintptr_t)alloc_obj);
943+
}
921944

922945
// TODO: only add when object needs obj_free to be called
923946
mmtk_buffer_obj_free_candidate(ractor_cache, (VALUE)alloc_obj);

gc/mmtk/mmtk.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ void mmtk_init_binding(MMTk_Builder *builder,
9797
const struct MMTk_RubyBindingOptions *binding_options,
9898
const struct MMTk_RubyUpcalls *upcalls);
9999

100+
size_t mmtk_get_vo_bit_log_region_size(void);
101+
102+
size_t mmtk_get_vo_bit_base_addr(void);
103+
100104
void mmtk_initialize_collection(MMTk_VMThread tls);
101105

102106
MMTk_Mutator *mmtk_bind_mutator(MMTk_VMMutatorThread tls);

gc/mmtk/src/api.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,16 @@ pub unsafe extern "C" fn mmtk_init_binding(
243243
.unwrap_or_else(|_| panic!("Binding is already initialized"));
244244
}
245245

246+
#[no_mangle]
247+
pub extern "C" fn mmtk_get_vo_bit_log_region_size() -> usize {
248+
mmtk::util::is_mmtk_object::VO_BIT_REGION_SIZE.trailing_zeros() as usize
249+
}
250+
251+
#[no_mangle]
252+
pub extern "C" fn mmtk_get_vo_bit_base_addr() -> usize {
253+
mmtk::util::metadata::side_metadata::vo_bit_side_metadata_addr().as_usize()
254+
}
255+
246256
#[no_mangle]
247257
pub extern "C" fn mmtk_initialize_collection(tls: VMThread) {
248258
memory_manager::initialize_collection(mmtk(), tls)

0 commit comments

Comments
 (0)