Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5cf6c84
rb_gc_obj_needs_cleanup_p: skip sweep for most imemo/fields
byroot Apr 8, 2026
d6528d6
compile.c: avoid needless rehash
byroot Apr 8, 2026
82470d8
Allow fixed size hashes to be allocated in smaller slots
byroot Apr 3, 2026
aa7e671
ZJIT: [DOC] induce_breakpoint! behaves differently when ZJIT is on
XrXr Apr 8, 2026
b53186a
ZJIT: Load immediate into register before masking (#16677)
tekknolagi Apr 8, 2026
b243209
ZJIT: Require Ruby 3.4+ in bisect script
tekknolagi Apr 8, 2026
64a4905
ZJIT: Detect bad configuration in make command in bisect script
tekknolagi Apr 8, 2026
9b6066c
ZJIT: Suggest correct command in bisect script
tekknolagi Apr 8, 2026
ddb60fe
ZJIT: Guard that an array is not frozen before modifying it
tekknolagi Apr 8, 2026
6ccabf1
ZJIT: Guard an array is not frozen before popping from it
tekknolagi Apr 8, 2026
a4fa75e
Bump taiki-e/install-action
dependabot[bot] Apr 9, 2026
f104525
mkmf: cpp_command in C++ mode
nobu Jan 28, 2021
aaa27ee
mkmf: Redirect egrep command input
nobu Apr 9, 2026
f4b5566
mkmf: grep all occurrences in cpp output
nobu Apr 9, 2026
4644e4f
[Bug #21986] Fix location of numeric literal
nobu Apr 9, 2026
4b6a467
mkmf: skip if C++ compiler not found
nobu Apr 9, 2026
c091c18
Fix thread leaks
nobu Apr 9, 2026
b94a7ec
Suppress rev-parse error message when out-of-place build
nobu Apr 9, 2026
0375703
mkmf: check for C++ compiler
nobu Apr 9, 2026
51a3f08
[ruby/prism] Reject `return` and similar with block pass argument
Earlopain Apr 9, 2026
ce9d6c8
Rename SIZE_POOL_COUNT to HEAP_COUNT in tests
eightbitraptor Mar 31, 2026
772bde3
Use sizeof(VALUE) for pointer alignment checks
eightbitraptor Mar 31, 2026
9371042
Guard rb_obj_embedded_size for zero fields
eightbitraptor Mar 31, 2026
2567e76
Handle small pools in shape capacity calculation
eightbitraptor Mar 31, 2026
c9b7088
Introduce power-of-two size pools
eightbitraptor Mar 31, 2026
b6658c1
Introduce RVALUE_SIZE GC constant
eightbitraptor Mar 31, 2026
aa5f192
Update tests for new pool layout
eightbitraptor Mar 31, 2026
5c968c5
Cache has_sweeping_pages as a bitfield
eightbitraptor Mar 31, 2026
a8009c9
Allow flex in heap growth threshold
eightbitraptor Mar 31, 2026
80e3a8d
Fix zjit hir tests
eightbitraptor Apr 2, 2026
2fd891f
Use the pre-processor to generate slot sizes and reciprocals
eightbitraptor Apr 6, 2026
5381f0f
Replace sweeping_heaps map with a counter
eightbitraptor Apr 6, 2026
3c28bb5
Make it obvious that field count guard is for debug
eightbitraptor Apr 6, 2026
c919778
Remove extra sentinel from shape capacities
eightbitraptor Apr 6, 2026
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
2 changes: 1 addition & 1 deletion .github/workflows/zjit-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ jobs:
rustup install ${{ matrix.rust_version }} --profile minimal
rustup default ${{ matrix.rust_version }}

- uses: taiki-e/install-action@cf39a74df4a72510be4e5b63348d61067f11e64a # v2.75.0
- uses: taiki-e/install-action@80e6af7a2ec7f280fffe2d0a9d3a12a9d11d86e9 # v2.75.1
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/zjit-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:
ruby-version: '3.1'
bundler: none

- uses: taiki-e/install-action@cf39a74df4a72510be4e5b63348d61067f11e64a # v2.75.0
- uses: taiki-e/install-action@80e6af7a2ec7f280fffe2d0a9d3a12a9d11d86e9 # v2.75.1
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
Expand Down
12 changes: 5 additions & 7 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -2731,7 +2731,6 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
data.len = len;
rb_hash_foreach(map, cdhash_set_label_i, (VALUE)&data);

rb_hash_rehash(map);
freeze_hide_obj(map);
rb_ractor_make_shareable(map);
generated_iseq[code_index + 1 + j] = map;
Expand Down Expand Up @@ -5373,10 +5372,10 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth
if (!RB_SPECIAL_CONST_P(elem[1])) RB_OBJ_SET_FROZEN_SHAREABLE(elem[1]);
rb_ary_cat(ary, elem, 2);
}
VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2);
VALUE hash = rb_hash_alloc_fixed_size(Qfalse, RARRAY_LEN(ary) / 2);
rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary), hash);
RB_GC_GUARD(ary);
hash = RB_OBJ_SET_FROZEN_SHAREABLE(rb_obj_hide(hash));
hash = RB_OBJ_SET_FROZEN_SHAREABLE(hash);

/* Emit optimized code */
FLUSH_CHUNK();
Expand Down Expand Up @@ -12168,7 +12167,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
case TS_CDHASH:
{
int i;
VALUE map = rb_hash_new_with_size(RARRAY_LEN(op)/2);
VALUE map = rb_hash_alloc_fixed_size(Qfalse, RARRAY_LEN(op)/2);

RHASH_TBL_RAW(map)->type = &cdhash_type;
op = rb_to_array_type(op);
Expand All @@ -12180,7 +12179,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
rb_hash_aset(map, key, (VALUE)label | 1);
}
RB_GC_GUARD(op);
RB_OBJ_SET_SHAREABLE(rb_obj_hide(map)); // allow mutation while compiling
RB_OBJ_SET_SHAREABLE(map); // allow mutation while compiling
argv[j] = map;
RB_OBJ_WRITTEN(iseq, Qundef, map);
}
Expand Down Expand Up @@ -14335,7 +14334,7 @@ static VALUE
ibf_load_object_hash(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
{
long len = (long)ibf_load_small_value(load, &offset);
VALUE obj = rb_hash_new_with_size(len);
VALUE obj = header->frozen ? rb_hash_alloc_fixed_size(rb_cHash, len) : rb_hash_new_with_size(len);
int i;

for (i = 0; i < len; i++) {
Expand All @@ -14346,7 +14345,6 @@ ibf_load_object_hash(const struct ibf_load *load, const struct ibf_object_header
VALUE val = ibf_load_object(load, val_index);
rb_hash_aset(obj, key, val);
}
rb_hash_rehash(obj);

if (header->internal) rb_obj_hide(obj);
if (header->frozen) {
Expand Down
2 changes: 1 addition & 1 deletion defs/gmake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ ifneq ($(DOT_WAIT),)
endif

ifeq ($(HAVE_GIT),yes)
REVISION_LATEST := $(shell $(GIT_IN_SRC) rev-parse HEAD)
REVISION_LATEST := $(shell $(GIT_IN_SRC) rev-parse HEAD 2>/dev/null)
else
REVISION_LATEST := update
endif
Expand Down
8 changes: 2 additions & 6 deletions ext/socket/lib/socket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -924,15 +924,11 @@ def self.tcp_with_fast_fallback(host, port, local_host = nil, local_port = nil,
end
end
ensure
hostname_resolution_threads.each do |thread|
thread.exit
end
hostname_resolution_threads.each(&:exit).each(&:join)

hostname_resolution_result&.close

connecting_sockets.each_key do |connecting_socket|
connecting_socket.close
end
connecting_sockets.each_key(&:close)
end
private_class_method :tcp_with_fast_fallback

Expand Down
30 changes: 29 additions & 1 deletion gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,34 @@ rb_gc_handle_weak_references(VALUE obj)
}
}

static inline bool
rb_gc_imemo_needs_cleanup_p(VALUE obj)
{
switch (imemo_type(obj)) {
case imemo_constcache:
case imemo_cref:
case imemo_ifunc:
case imemo_memo:
case imemo_svar:
case imemo_callcache:
case imemo_throw_data:
return false;

case imemo_env:
case imemo_ment:
case imemo_iseq:
case imemo_callinfo:
return true;

case imemo_tmpbuf:
return ((rb_imemo_tmpbuf_t *)obj)->ptr != NULL;

case imemo_fields:
return FL_TEST_RAW(obj, OBJ_FIELD_HEAP) || (id2ref_tbl && rb_shape_obj_has_id(obj));
}
UNREACHABLE_RETURN(true);
}

/*
* Returns true if the object requires a full rb_gc_obj_free() call during sweep,
* false if it can be freed quickly without calling destructors or cleanup.
Expand All @@ -1313,7 +1341,7 @@ rb_gc_obj_needs_cleanup_p(VALUE obj)

switch (flags & RUBY_T_MASK) {
case T_IMEMO:
return rb_imemo_needs_cleanup_p(obj);
return rb_gc_imemo_needs_cleanup_p(obj);

case T_DATA:
case T_OBJECT:
Expand Down
35 changes: 22 additions & 13 deletions gc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -269,43 +269,52 @@ def self.stat hash_or_key = nil
# GC.stat_heap
# # =>
# {0 =>
# {slot_size: 40,
# {slot_size: 32,
# heap_eden_pages: 24,
# heap_eden_slots: 12288,
# total_allocated_pages: 24,
# force_major_gc_count: 0,
# force_incremental_marking_finish_count: 0,
# total_allocated_objects: 8450,
# total_freed_objects: 3120},
# 1 =>
# {slot_size: 64,
# heap_eden_pages: 246,
# heap_eden_slots: 402802,
# total_allocated_pages: 246,
# force_major_gc_count: 2,
# force_incremental_marking_finish_count: 1,
# total_allocated_objects: 33867152,
# total_freed_objects: 33520523},
# 1 =>
# {slot_size: 80,
# 2 =>
# {slot_size: 128,
# heap_eden_pages: 84,
# heap_eden_slots: 68746,
# total_allocated_pages: 84,
# force_major_gc_count: 1,
# force_incremental_marking_finish_count: 4,
# total_allocated_objects: 147491,
# total_freed_objects: 90699},
# 2 =>
# {slot_size: 160,
# 3 =>
# {slot_size: 256,
# heap_eden_pages: 157,
# heap_eden_slots: 64182,
# total_allocated_pages: 157,
# force_major_gc_count: 0,
# force_incremental_marking_finish_count: 0,
# total_allocated_objects: 211460,
# total_freed_objects: 190075},
# 3 =>
# {slot_size: 320,
# 4 =>
# {slot_size: 512,
# heap_eden_pages: 8,
# heap_eden_slots: 1631,
# total_allocated_pages: 8,
# force_major_gc_count: 0,
# force_incremental_marking_finish_count: 0,
# total_allocated_objects: 1422,
# total_freed_objects: 700},
# 4 =>
# {slot_size: 640,
# 5 =>
# {slot_size: 1024,
# heap_eden_pages: 16,
# heap_eden_slots: 1628,
# total_allocated_pages: 16,
Expand All @@ -316,17 +325,17 @@ def self.stat hash_or_key = nil
#
# In the example above, the keys in the outer hash are the heap identifiers:
#
# GC.stat_heap.keys # => [0, 1, 2, 3, 4]
# GC.stat_heap.keys # => [0, 1, 2, 3, 4, 5]
#
# On CRuby, each heap identifier is an integer;
# on other implementations, a heap identifier may be a string.
#
# With only argument +heap_id+ given,
# returns statistics for the given heap identifier:
#
# GC.stat_heap(2)
# GC.stat_heap(3)
# # =>
# {slot_size: 160,
# {slot_size: 256,
# heap_eden_pages: 157,
# heap_eden_slots: 64182,
# total_allocated_pages: 157,
Expand All @@ -338,7 +347,7 @@ def self.stat hash_or_key = nil
# With arguments +heap_id+ and +key+ given,
# returns the value for the given key in the given heap:
#
# GC.stat_heap(2, :slot_size) # => 160
# GC.stat_heap(3, :slot_size) # => 256
#
# With arguments +nil+ and +hash+ given,
# merges the statistics for all heaps into the given hash:
Expand Down
Loading