Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions depend
Original file line number Diff line number Diff line change
Expand Up @@ -6731,6 +6731,7 @@ hash.$(OBJEXT): {$(VPATH)}vm_core.h
hash.$(OBJEXT): {$(VPATH)}vm_debug.h
hash.$(OBJEXT): {$(VPATH)}vm_opts.h
hash.$(OBJEXT): {$(VPATH)}vm_sync.h
hash.$(OBJEXT): {$(VPATH)}zjit.h
imemo.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
imemo.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
imemo.$(OBJEXT): $(CCAN_DIR)/list/list.h
Expand Down Expand Up @@ -7848,6 +7849,7 @@ jit.$(OBJEXT): $(top_srcdir)/internal/compile.h
jit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
jit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
jit.$(OBJEXT): $(top_srcdir)/internal/gc.h
jit.$(OBJEXT): $(top_srcdir)/internal/hash.h
jit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
jit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
jit.$(OBJEXT): $(top_srcdir)/internal/serial.h
Expand Down Expand Up @@ -8013,6 +8015,7 @@ jit.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
jit.$(OBJEXT): {$(VPATH)}internal/has/extension.h
jit.$(OBJEXT): {$(VPATH)}internal/has/feature.h
jit.$(OBJEXT): {$(VPATH)}internal/has/warning.h
jit.$(OBJEXT): {$(VPATH)}internal/hash.h
jit.$(OBJEXT): {$(VPATH)}internal/intern/array.h
jit.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
jit.$(OBJEXT): {$(VPATH)}internal/intern/class.h
Expand Down
138 changes: 49 additions & 89 deletions gc/default/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,17 @@ static RB_THREAD_LOCAL_SPECIFIER int malloc_increase_local;
#endif

typedef struct ractor_newobj_heap_cache {
uintptr_t cursor;
uintptr_t cursor_end;
struct free_region *next_region;
struct heap_page *using_page;
uintptr_t region_end;
size_t allocated_objects_count;
} rb_ractor_newobj_heap_cache_t;

typedef struct ractor_newobj_cache {
size_t incremental_mark_step_allocated_slots;
rb_ractor_newobj_heap_cache_t heap_caches[HEAP_COUNT];
struct gc_bump_pointer_heap bump_heaps[];
} rb_ractor_newobj_cache_t;

typedef struct {
Expand Down Expand Up @@ -1764,31 +1766,11 @@ calloc1(size_t n)
return calloc(1, n);
}

static void
gc_ractor_jit_cursor_sync(void *c, void *data)
{
rb_ractor_newobj_cache_t *gc_cache = c;
bool tracing = (bool)(uintptr_t)data;

for (size_t heap_idx = 0; heap_idx < HEAP_COUNT; heap_idx++) {
struct gc_bump_pointer_heap *bump = &gc_cache->bump_heaps[heap_idx];
bump->jit_cursor_end = tracing ? bump->cursor : bump->cursor_end;
}
}

void
rb_gc_impl_set_event_hook(void *objspace_ptr, const rb_event_flag_t event)
{
rb_objspace_t *objspace = objspace_ptr;
rb_event_flag_t old_events = objspace->hook_events;
objspace->hook_events = event & RUBY_INTERNAL_EVENT_OBJSPACE_MASK;

bool was_tracing = old_events & RUBY_INTERNAL_EVENT_NEWOBJ;
bool now_tracing = objspace->hook_events & RUBY_INTERNAL_EVENT_NEWOBJ;
if (was_tracing != now_tracing) {
rb_gc_ractor_newobj_cache_foreach(gc_ractor_jit_cursor_sync,
(void *)(uintptr_t)now_tracing);
}
}

unsigned long long
Expand Down Expand Up @@ -2498,46 +2480,41 @@ rb_gc_impl_size_allocatable_p(size_t size)
}

static inline void
gc_bump_flush_alloc_count(struct gc_bump_pointer_heap *bump, rb_heap_t *heap)
gc_bump_flush_alloc_count(rb_ractor_newobj_heap_cache_t *heap_cache, rb_heap_t *heap)
{
if (bump->slot_size == 0) return;

size_t n = (bump->cursor - bump->region_start) / bump->slot_size;
if (n > 0) {
RUBY_ATOMIC_SIZE_ADD(heap->total_allocated_objects, n);
bump->region_start = bump->cursor;
if (heap_cache->allocated_objects_count > 0) {
RUBY_ATOMIC_SIZE_ADD(heap->total_allocated_objects, heap_cache->allocated_objects_count);
heap_cache->allocated_objects_count = 0;
}
}

static void
ractor_cache_flush_count(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *gc_cache)
{
for (int heap_idx = 0; heap_idx < HEAP_COUNT; heap_idx++) {
gc_bump_flush_alloc_count(&gc_cache->bump_heaps[heap_idx], &heaps[heap_idx]);
gc_bump_flush_alloc_count(&gc_cache->heap_caches[heap_idx], &heaps[heap_idx]);
}
}

static inline void
ractor_cache_open_window(rb_objspace_t *objspace, struct gc_bump_pointer_heap *bump,
rb_ractor_newobj_heap_cache_t *heap_cache)
ractor_cache_open_window(rb_objspace_t *objspace, rb_ractor_newobj_heap_cache_t *heap_cache,
size_t heap_idx)
{
uintptr_t end = heap_cache->region_end;

if (RB_UNLIKELY(is_incremental_marking(objspace))) {
uintptr_t window_end = bump->cursor + INCREMENTAL_MARK_STEP_ALLOCATIONS * bump->slot_size;
uintptr_t window_end = heap_cache->cursor + INCREMENTAL_MARK_STEP_ALLOCATIONS * pool_slot_sizes[heap_idx];
if (window_end < end) end = window_end;
}

bump->cursor_end = end;
bump->jit_cursor_end =
RB_UNLIKELY(objspace->hook_events & RUBY_INTERNAL_EVENT_NEWOBJ) ? bump->cursor : end;
heap_cache->cursor_end = end;
}

static inline bool
ractor_cache_advance_region(rb_objspace_t *objspace, struct gc_bump_pointer_heap *bump,
rb_ractor_newobj_heap_cache_t *heap_cache, rb_heap_t *heap)
ractor_cache_advance_region(rb_objspace_t *objspace, rb_ractor_newobj_heap_cache_t *heap_cache,
size_t heap_idx)
{
gc_bump_flush_alloc_count(bump, heap);
gc_bump_flush_alloc_count(heap_cache, &heaps[heap_idx]);

struct free_region *region = heap_cache->next_region;
if (region == NULL) {
Expand All @@ -2546,13 +2523,12 @@ ractor_cache_advance_region(rb_objspace_t *objspace, struct gc_bump_pointer_heap

rb_asan_unpoison_object((VALUE)region, false);
GC_ASSERT(RB_TYPE_P((VALUE)region, T_NONE));
bump->cursor = (uintptr_t)region;
bump->region_start = (uintptr_t)region;
heap_cache->cursor = (uintptr_t)region;
heap_cache->region_end = region->end;
heap_cache->next_region = region->next;
rb_asan_poison_object((VALUE)region);

ractor_cache_open_window(objspace, bump, heap_cache);
ractor_cache_open_window(objspace, heap_cache, heap_idx);

return true;
}
Expand All @@ -2561,24 +2537,25 @@ static inline VALUE
ractor_cache_allocate_slot(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *gc_cache,
size_t heap_idx)
{
struct gc_bump_pointer_heap *bump = &gc_cache->bump_heaps[heap_idx];
rb_ractor_newobj_heap_cache_t *heap_cache = &gc_cache->heap_caches[heap_idx];
size_t slot_size = pool_slot_sizes[heap_idx];

uintptr_t cursor = bump->cursor;
if (RB_UNLIKELY(cursor + bump->slot_size > bump->cursor_end)) {
uintptr_t cursor = heap_cache->cursor;
if (RB_UNLIKELY(cursor + slot_size > heap_cache->cursor_end)) {
if (RB_UNLIKELY(is_incremental_marking(objspace))) {
return Qfalse;
}

rb_ractor_newobj_heap_cache_t *heap_cache = &gc_cache->heap_caches[heap_idx];
if (!ractor_cache_advance_region(objspace, bump, heap_cache, &heaps[heap_idx])) {
if (!ractor_cache_advance_region(objspace, heap_cache, heap_idx)) {
return Qfalse;
}
cursor = bump->cursor;
cursor = heap_cache->cursor;
}

VALUE obj = (VALUE)cursor;
rb_asan_unpoison_object(obj, true);
bump->cursor = cursor + bump->slot_size;
heap_cache->cursor = cursor + slot_size;
heap_cache->allocated_objects_count++;

#if RGENGC_CHECK_MODE
GC_ASSERT(rb_gc_impl_obj_slot_size(obj) == heap_slot_size(heap_idx));
Expand Down Expand Up @@ -2612,10 +2589,9 @@ ractor_cache_set_page(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *gc_cach
{
gc_report(3, objspace, "ractor_set_cache: Using page %p\n", (void *)page->body);

struct gc_bump_pointer_heap *bump = &gc_cache->bump_heaps[heap_idx];
rb_ractor_newobj_heap_cache_t *heap_cache = &gc_cache->heap_caches[heap_idx];

GC_ASSERT(bump->cursor + bump->slot_size > bump->cursor_end);
GC_ASSERT(heap_cache->cursor + pool_slot_sizes[heap_idx] > heap_cache->cursor_end);
GC_ASSERT(heap_cache->next_region == NULL);
GC_ASSERT(page->free_slots != 0);
GC_ASSERT(page->free_region != NULL);
Expand All @@ -2625,13 +2601,12 @@ ractor_cache_set_page(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *gc_cach
struct free_region *region = page->free_region;
rb_asan_unpoison_object((VALUE)region, false);
GC_ASSERT(RB_TYPE_P((VALUE)region, T_NONE));
bump->cursor = (uintptr_t)region;
bump->region_start = (uintptr_t)region;
heap_cache->cursor = (uintptr_t)region;
heap_cache->region_end = region->end;
heap_cache->next_region = region->next;
rb_asan_poison_object((VALUE)region);

ractor_cache_open_window(objspace, bump, heap_cache);
ractor_cache_open_window(objspace, heap_cache, heap_idx);

page->free_slots = 0;
page->free_region = NULL;
Expand Down Expand Up @@ -2684,12 +2659,12 @@ rb_gc_impl_zjit_new_obj_fastpath(void *objspace_ptr, size_t alloc_size, VALUE fl
}
if (slot_size == 0) return false;

size_t bump_base = offsetof(rb_ractor_newobj_cache_t, bump_heaps) +
heap_idx * sizeof(struct gc_bump_pointer_heap);
size_t base = offsetof(rb_ractor_newobj_cache_t, heap_caches) +
heap_idx * sizeof(rb_ractor_newobj_heap_cache_t);

struct rb_gc_zjit_default_new_obj_fastpath default_fastpath = {
bump_base + offsetof(struct gc_bump_pointer_heap, cursor),
bump_base + offsetof(struct gc_bump_pointer_heap, jit_cursor_end),
base + offsetof(rb_ractor_newobj_heap_cache_t, cursor),
base + offsetof(rb_ractor_newobj_heap_cache_t, cursor_end),
slot_size,
flags,
klass
Expand All @@ -2710,7 +2685,6 @@ NOINLINE(static VALUE newobj_bump_pointer_miss(rb_objspace_t *objspace, rb_racto
static VALUE
newobj_bump_pointer_miss(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *gc_cache, size_t heap_idx, bool vm_locked)
{
struct gc_bump_pointer_heap *bump = &gc_cache->bump_heaps[heap_idx];
rb_ractor_newobj_cache_t *cache = gc_cache;
rb_ractor_newobj_heap_cache_t *heap_cache = &cache->heap_caches[heap_idx];
rb_heap_t *heap = &heaps[heap_idx];
Expand Down Expand Up @@ -2743,25 +2717,22 @@ newobj_bump_pointer_miss(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *gc_c
}

if (is_incremental_marking(objspace)) {
if (bump->slot_size > 0) {
cache->incremental_mark_step_allocated_slots +=
(bump->cursor - bump->region_start) / bump->slot_size;
}
gc_bump_flush_alloc_count(bump, heap);
cache->incremental_mark_step_allocated_slots += heap_cache->allocated_objects_count;
gc_bump_flush_alloc_count(heap_cache, heap);

if (cache->incremental_mark_step_allocated_slots >= INCREMENTAL_MARK_STEP_ALLOCATIONS) {
gc_continue(objspace, heap);
cache->incremental_mark_step_allocated_slots = 0;
}

if (bump->cursor + bump->slot_size <= heap_cache->region_end) {
ractor_cache_open_window(objspace, bump, heap_cache);
if (heap_cache->cursor + pool_slot_sizes[heap_idx] <= heap_cache->region_end) {
ractor_cache_open_window(objspace, heap_cache, heap_idx);
obj = ractor_cache_allocate_slot(objspace, gc_cache, heap_idx);
}
}

if (obj == Qfalse) {
if (ractor_cache_advance_region(objspace, bump, heap_cache, heap)) {
if (ractor_cache_advance_region(objspace, heap_cache, heap_idx)) {
obj = ractor_cache_allocate_slot(objspace, gc_cache, heap_idx);
}
}
Expand All @@ -2774,8 +2745,7 @@ newobj_bump_pointer_miss(rb_objspace_t *objspace, rb_ractor_newobj_cache_t *gc_c
}

if (RB_UNLIKELY(ruby_gc_stressful)) {
bump->cursor_end = bump->cursor;
bump->jit_cursor_end = bump->cursor;
heap_cache->cursor_end = heap_cache->cursor;
}
}

Expand Down Expand Up @@ -4112,13 +4082,12 @@ gc_mode_transition(rb_objspace_t *objspace, enum gc_mode mode)
}

static void
heap_page_flush_cache_regions(struct heap_page *page, struct gc_bump_pointer_heap *bump,
rb_ractor_newobj_heap_cache_t *heap_cache)
heap_page_flush_cache_regions(struct heap_page *page, rb_ractor_newobj_heap_cache_t *heap_cache)
{
struct free_region *chain = heap_cache->next_region;

if (bump->cursor < heap_cache->region_end) {
VALUE start = (VALUE)bump->cursor;
if (heap_cache->cursor < heap_cache->region_end) {
VALUE start = (VALUE)heap_cache->cursor;
rb_asan_unpoison_object(start, false);
struct free_region *remnant = (struct free_region *)start;
remnant->flags = 0;
Expand Down Expand Up @@ -4186,26 +4155,23 @@ gc_ractor_newobj_cache_clear(void *c, void *data)
newobj_cache->incremental_mark_step_allocated_slots = 0;

for (size_t heap_idx = 0; heap_idx < HEAP_COUNT; heap_idx++) {
struct gc_bump_pointer_heap *bump = &gc_cache->bump_heaps[heap_idx];
rb_ractor_newobj_heap_cache_t *cache = &newobj_cache->heap_caches[heap_idx];

rb_heap_t *heap = &heaps[heap_idx];
gc_bump_flush_alloc_count(bump, heap);
gc_bump_flush_alloc_count(cache, heap);

struct heap_page *page = cache->using_page;
RUBY_DEBUG_LOG("ractor using_page:%p cursor:%p", (void *)page, (void *)bump->cursor);
RUBY_DEBUG_LOG("ractor using_page:%p cursor:%p", (void *)page, (void *)cache->cursor);

if (page) {
heap_page_flush_cache_regions(page, bump, cache);
heap_page_flush_cache_regions(page, cache);
}

cache->using_page = NULL;
cache->next_region = NULL;
cache->region_end = 0;
bump->cursor = 0;
bump->cursor_end = 0;
bump->jit_cursor_end = 0;
bump->region_start = 0;
cache->cursor = 0;
cache->cursor_end = 0;
}
}

Expand All @@ -4215,9 +4181,8 @@ gc_ractor_newobj_cache_exhaust(void *c, void *data)
rb_ractor_newobj_cache_t *gc_cache = c;

for (size_t heap_idx = 0; heap_idx < HEAP_COUNT; heap_idx++) {
struct gc_bump_pointer_heap *bump = &gc_cache->bump_heaps[heap_idx];
bump->cursor_end = bump->cursor;
bump->jit_cursor_end = bump->cursor;
rb_ractor_newobj_heap_cache_t *heap_cache = &gc_cache->heap_caches[heap_idx];
heap_cache->cursor_end = heap_cache->cursor;
}
}

Expand Down Expand Up @@ -6826,13 +6791,8 @@ rb_gc_impl_ractor_cache_alloc(void *objspace_ptr, void *ractor)

objspace->live_ractor_cache_count++;

rb_ractor_newobj_cache_t *gc_cache =
calloc1(sizeof(rb_ractor_newobj_cache_t) +
sizeof(struct gc_bump_pointer_heap) * (HEAP_COUNT + 1));
rb_ractor_newobj_cache_t *gc_cache = calloc1(sizeof(rb_ractor_newobj_cache_t));

for (size_t i = 0; i < HEAP_COUNT; i++) {
gc_cache->bump_heaps[i].slot_size = pool_slot_sizes[i];
}
return gc_cache;
}

Expand Down
2 changes: 1 addition & 1 deletion gc/default/zjit_fastpath.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

struct rb_gc_zjit_default_new_obj_fastpath {
size_t cursor_offset;
size_t jit_cursor_end_offset;
size_t cursor_end_offset;
size_t slot_size;
VALUE flags;
VALUE klass;
Expand Down
8 changes: 0 additions & 8 deletions gc/gc_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@
#include <stddef.h>
#include <stdint.h>

struct gc_bump_pointer_heap {
uintptr_t cursor;
uintptr_t cursor_end;
uintptr_t jit_cursor_end;
uintptr_t region_start;
size_t slot_size;
};

enum rb_gc_zjit_fastpath_kind {
RB_GC_ZJIT_FASTPATH_DEFAULT = 1,
RB_GC_ZJIT_FASTPATH_MMTK = 2,
Expand Down
Loading