Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
60de70c
[ruby/rubygems] Improve error message when current platform is not in…
55728 Mar 29, 2026
20af0e9
Add retry logic to stdgems.org curl requests in CI
k0kubun Apr 1, 2026
05086ee
Bump taiki-e/install-action
dependabot[bot] Apr 1, 2026
1a668de
pty: Rename as the purpose
nobu Apr 1, 2026
2477916
pty: Fix missing arguments
nobu Apr 1, 2026
5309963
Make `ruby_xfree_sized` and `ruby_xrealloc_sized` public
byroot Mar 30, 2026
a9b8d47
[ruby/rubygems] Merge rubygems-attestation-patch.rb from rubygems/rel…
hsbt Feb 10, 2026
2041c87
[ruby/rubygems] Refactor push request to support attestations
hsbt Feb 10, 2026
e35eaf5
[ruby/rubygems] Added test for auto-attestation
hsbt Feb 10, 2026
bf61731
[ruby/rubygems] Add test coverage for skipping auto-attestation
Copilot Feb 10, 2026
c4eeb67
[ruby/rubygems] Remove raise from stub to rely on flag for test asser…
Copilot Feb 10, 2026
6ef9fe5
[ruby/rubygems] Use Tempfile for auto-attestation bundles and clean u…
Copilot Feb 10, 2026
d2f9872
[ruby/rubygems] Omit tests of auto-attestation with JRuby
hsbt Feb 10, 2026
54ce911
[ruby/rubygems] Reverse to use attestation condition
hsbt Feb 24, 2026
8047213
[ruby/rubygems] Honor explicit --attestation option regardless of pla…
hsbt Apr 1, 2026
b9358e9
[ruby/rubygems] Show only error message on attestation failure unless…
hsbt Apr 1, 2026
a27f303
[ruby/rubygems] Normalize host comparison in attestation_supported_host?
hsbt Apr 1, 2026
3f1aced
[ruby/rubygems] Use gem exec --conservative for sigstore-cli instead …
hsbt Apr 1, 2026
9a2ffd8
Fix sending backtraces across ractors
byroot Mar 24, 2026
ce398d7
[ruby/prism] Remove a warning from `discarded-qualifiers`
Earlopain Apr 1, 2026
9224d90
Refactor socket timestamp tests
nobu Apr 1, 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/bundled_gems.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
mkdir -p .downloaded-cache
for data in bundled_gems.json default_gems.json; do
ln -s .downloaded-cache/$data .
curl -O -R -z ./$data https://stdgems.org/$data
curl --retry 5 --retry-connrefused --retry-delay 2 --retry-max-time 60 -O -R -z ./$data https://stdgems.org/$data
done

- name: Update bundled gems list
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/default_gems_list.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
data=default_gems.json
mkdir -p .downloaded-cache
ln -s .downloaded-cache/$data .
curl -O -R -z ./$data https://stdgems.org/$data
curl --retry 5 --retry-connrefused --retry-delay 2 --retry-max-time 60 -O -R -z ./$data https://stdgems.org/$data
if: ${{ steps.gems.outcome == 'success' }}

- name: Make default gems list
Expand Down
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@6ef672efc2b5aabc787a9e94baf4989aa02a97df # v2.70.3
- uses: taiki-e/install-action@bfadeaba214680fb4ab63e710bcb2a6a17019fdc # v2.70.4
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@6ef672efc2b5aabc787a9e94baf4989aa02a97df # v2.70.3
- uses: taiki-e/install-action@bfadeaba214680fb4ab63e710bcb2a6a17019fdc # v2.70.4
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
Expand Down
13 changes: 13 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,18 @@ Ruby 4.0 bundled RubyGems and Bundler version 4. see the following links for det
and in some case memory usage.
See the C extension documentation for details. [[Feature #21853]]

* Added new C23 inspired allocator functions, that takes the previous memory size.
This allow the Ruby GC to better keep track of memory usage, improving its heuristics.
It also improves the performance of system allocators that support C23 `free_sized`.

However, it is important to note that passing an incorrect size to these function is undefined
behavior and may result in crashes or memory leaks.

- `ruby_xfree_sized(void *ptr, size_t size)`
- `ruby_xrealloc_sized(void *ptr, size_t newsiz, size_t oldsiz)`
- `ruby_xrealloc2_sized(void *ptr, size_t newelems, size_t newsiz, size_t oldelems)`

[[Feature #21861]]

## Implementation improvements

Expand All @@ -144,6 +156,7 @@ A lot of work has gone into making Ractors more stable, performant, and usable.
[Feature #21390]: https://bugs.ruby-lang.org/issues/21390
[Feature #21785]: https://bugs.ruby-lang.org/issues/21785
[Feature #21853]: https://bugs.ruby-lang.org/issues/21853
[Feature #21861]: https://bugs.ruby-lang.org/issues/21861
[Feature #21932]: https://bugs.ruby-lang.org/issues/21932
[test-unit-3.7.4]: https://github.com/test-unit/test-unit/releases/tag/3.7.4
[test-unit-3.7.5]: https://github.com/test-unit/test-unit/releases/tag/3.7.5
Expand Down
4 changes: 2 additions & 2 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ ary_heap_alloc_buffer(size_t capa)
static void
ary_heap_free_ptr(VALUE ary, const VALUE *ptr, long size)
{
ruby_sized_xfree((void *)ptr, size);
ruby_xfree_sized((void *)ptr, size);
}

static void
Expand Down Expand Up @@ -2427,7 +2427,7 @@ rb_ary_resize(VALUE ary, long len)
MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len); /* WB: no new reference */
ARY_SET_EMBED_LEN(ary, len);

if (is_malloc_ptr) ruby_sized_xfree((void *)ptr, ptr_capa);
if (is_malloc_ptr) ruby_xfree_sized((void *)ptr, ptr_capa);
}
else {
if (olen > len + ARY_DEFAULT_SIZE) {
Expand Down
2 changes: 1 addition & 1 deletion bootstraptest/test_ractor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ def test n
}

# To copy the object, now Marshal#dump is used
assert_match /can not copy unshareable object/, %q{
assert_match /can't clone unshareable instance of Thread/, %q{
obj = Thread.new{}
begin
r = Ractor.new obj do |msg|
Expand Down
4 changes: 2 additions & 2 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,7 +1666,7 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
debugs("[compile step 6.1 (remove unused catch tables)] \n");
RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq));
if (!ISEQ_COMPILE_DATA(iseq)->catch_except_p && ISEQ_BODY(iseq)->catch_table) {
ruby_sized_xfree(ISEQ_BODY(iseq)->catch_table, iseq_catch_table_bytes(ISEQ_BODY(iseq)->catch_table->size));
ruby_xfree_sized(ISEQ_BODY(iseq)->catch_table, iseq_catch_table_bytes(ISEQ_BODY(iseq)->catch_table->size));
ISEQ_BODY(iseq)->catch_table = NULL;
}

Expand Down Expand Up @@ -13315,7 +13315,7 @@ ibf_load_local_table(const struct ibf_load *load, ibf_offset_t local_table_offse
}

if (size == 1 && table[0] == idERROR_INFO) {
ruby_sized_xfree(table, sizeof(ID) * size);
ruby_xfree_sized(table, sizeof(ID) * size);
return rb_iseq_shared_exc_local_tbl;
}
else {
Expand Down
8 changes: 3 additions & 5 deletions darray.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,12 @@ rb_darray_free(void *ary)
xfree(ary);
}

void ruby_sized_xfree(void *x, size_t size);

static inline void
rb_darray_free_sized0(void *ary, size_t element_size)
{
const rb_darray_meta_t *meta = ary;
if (meta) {
ruby_sized_xfree(ary, sizeof(*meta) + (element_size * meta->capa));
ruby_xfree_sized(ary, sizeof(*meta) + (element_size * meta->capa));
}
}
#define rb_darray_free_sized(ary, T) rb_darray_free_sized0((ary), sizeof(T))
Expand Down Expand Up @@ -203,7 +201,7 @@ rb_darray_calloc_mul_add_without_gc(size_t x, size_t y, size_t z)
return ptr;
}

void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size);
void *ruby_xrealloc_sized(void *ptr, size_t new_size, size_t old_size);

/* Internal function. Like rb_xrealloc_mul_add. */
static inline void *
Expand All @@ -212,7 +210,7 @@ rb_darray_realloc_mul_add(void *orig_ptr, size_t capa, size_t element_size, size
size_t size = rbimpl_size_add_or_raise(rbimpl_size_mul_or_raise(capa, element_size), header_size);
size_t old_size = (rb_darray_capa(orig_ptr) * element_size) + header_size; // We know it won't overflow

void *ptr = ruby_sized_xrealloc(orig_ptr, size, old_size);
void *ptr = ruby_xrealloc_sized(orig_ptr, size, old_size);
RUBY_ASSERT(ptr != NULL);

return ptr;
Expand Down
1 change: 1 addition & 0 deletions defs/id.def
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ firstline, predefined = __LINE__+1, %[\
send
__send__
__recursive_key__
clone
initialize
initialize_copy
initialize_clone
Expand Down
1 change: 1 addition & 0 deletions depend
Original file line number Diff line number Diff line change
Expand Up @@ -19980,6 +19980,7 @@ vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/error.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/gc.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/object.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/set_table.h
Expand Down
14 changes: 7 additions & 7 deletions ext/pty/pty.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,8 @@ ptsname_r(int fd, char *buf, size_t buflen)
#endif

#if defined(HAVE_POSIX_OPENPT) || defined(HAVE_OPENPTY) || defined(HAVE_PTSNAME_R)
static int
set_device_mode(const char *slavedevice, int fd, int nomesg)
static inline int
prevent_messages(const char *slavedevice, int fd, int nomesg)
{
if (nomesg)
return change_mode(slavedevice, fd, 0600);
Expand Down Expand Up @@ -352,7 +352,7 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
if (ptsname_r(masterfd, SlaveName, DEVICELEN) != 0) goto error;
slavedevice = SlaveName;
if ((slavefd = rb_cloexec_open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error;
if (set_device_mode(slavedevice, slavefd, nomesg) == -1) goto error;
if (prevent_messages(slavedevice, slavefd, nomesg) == -1) goto error;
rb_update_max_fd(slavefd);

#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX)
Expand Down Expand Up @@ -386,7 +386,7 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
}
rb_fd_fix_cloexec(*master);
rb_fd_fix_cloexec(*slave);
if (set_device_mode(SlaveName, *slave, nomesg) == -1) {
if (prevent_messages(SlaveName, *slave, nomesg) == -1) {
close(*master);
close(*slave);
if (!fail) return -1;
Expand Down Expand Up @@ -438,7 +438,7 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
if (ptsname_r(masterfd, SlaveName, DEVICELEN) != 0) goto error;
slavedevice = SlaveName;
if((slavefd = rb_cloexec_open(slavedevice, O_RDWR, 0)) == -1) goto error;
if (set_device_mode(slavedevice, slavefd, nomesg) == -1) goto error;
if (prevent_messages(slavedevice, slavefd, nomesg) == -1) goto error;
rb_update_max_fd(slavefd);
#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX)
if(ioctl_I_PUSH(slavefd, "ptem") == -1) goto error;
Expand Down Expand Up @@ -491,8 +491,8 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
if ((slavefd = rb_cloexec_open(SlaveName,O_RDWR,0)) >= 0) {
rb_update_max_fd(slavefd);
*slave = slavefd;
if (change_owner(slavefd, getuid(), getgid()) != 0) goto error;
if (change_mode(slavefd, nomesg ? 0600 : 0622) != 0) goto error;
if (change_owner(SlaveName, slavefd, getuid(), getgid()) != 0) goto error;
if (change_mode(SlaveName, slavefd, nomesg ? 0600 : 0622) != 0) goto error;
return 0;
}
close(masterfd);
Expand Down
36 changes: 18 additions & 18 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -5417,19 +5417,19 @@ ruby_xcalloc_body(size_t n, size_t size)
return rb_gc_impl_calloc(rb_gc_get_objspace(), xmalloc2_size(n, size), malloc_gc_allowed());
}

static void *ruby_sized_xrealloc_body(void *ptr, size_t new_size, size_t old_size);
static void *ruby_xrealloc_sized_body(void *ptr, size_t new_size, size_t old_size);

#ifdef ruby_sized_xrealloc
#undef ruby_sized_xrealloc
#ifdef ruby_xrealloc_sized
#undef ruby_xrealloc_sized
#endif
void *
ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size)
ruby_xrealloc_sized(void *ptr, size_t new_size, size_t old_size)
{
return handle_malloc_failure(ruby_sized_xrealloc_body(ptr, new_size, old_size));
return handle_malloc_failure(ruby_xrealloc_sized_body(ptr, new_size, old_size));
}

static void *
ruby_sized_xrealloc_body(void *ptr, size_t new_size, size_t old_size)
ruby_xrealloc_sized_body(void *ptr, size_t new_size, size_t old_size)
{
if ((ssize_t)new_size < 0) {
negative_size_allocation_error("too large allocation size");
Expand All @@ -5441,22 +5441,22 @@ ruby_sized_xrealloc_body(void *ptr, size_t new_size, size_t old_size)
void *
ruby_xrealloc(void *ptr, size_t new_size)
{
return ruby_sized_xrealloc(ptr, new_size, 0);
return ruby_xrealloc_sized(ptr, new_size, 0);
}

static void *ruby_sized_xrealloc2_body(void *ptr, size_t n, size_t size, size_t old_n);
static void *ruby_xrealloc2_sized_body(void *ptr, size_t n, size_t size, size_t old_n);

#ifdef ruby_sized_xrealloc2
#undef ruby_sized_xrealloc2
#ifdef ruby_xrealloc2_sized
#undef ruby_xrealloc2_sized
#endif
void *
ruby_sized_xrealloc2(void *ptr, size_t n, size_t size, size_t old_n)
ruby_xrealloc2_sized(void *ptr, size_t n, size_t size, size_t old_n)
{
return handle_malloc_failure(ruby_sized_xrealloc2_body(ptr, n, size, old_n));
return handle_malloc_failure(ruby_xrealloc2_sized_body(ptr, n, size, old_n));
}

static void *
ruby_sized_xrealloc2_body(void *ptr, size_t n, size_t size, size_t old_n)
ruby_xrealloc2_sized_body(void *ptr, size_t n, size_t size, size_t old_n)
{
size_t len = xmalloc2_size(n, size);
return rb_gc_impl_realloc(rb_gc_get_objspace(), ptr, len, old_n * size, malloc_gc_allowed());
Expand All @@ -5465,14 +5465,14 @@ ruby_sized_xrealloc2_body(void *ptr, size_t n, size_t size, size_t old_n)
void *
ruby_xrealloc2(void *ptr, size_t n, size_t size)
{
return ruby_sized_xrealloc2(ptr, n, size, 0);
return ruby_xrealloc2_sized(ptr, n, size, 0);
}

#ifdef ruby_sized_xfree
#undef ruby_sized_xfree
#ifdef ruby_xfree_sized
#undef ruby_xfree_sized
#endif
void
ruby_sized_xfree(void *x, size_t size)
ruby_xfree_sized(void *x, size_t size)
{
if (LIKELY(x)) {
/* It's possible for a C extension's pthread destructor function set by pthread_key_create
Expand All @@ -5490,7 +5490,7 @@ ruby_sized_xfree(void *x, size_t size)
void
ruby_xfree(void *x)
{
ruby_sized_xfree(x, 0);
ruby_xfree_sized(x, 0);
}

void *
Expand Down
6 changes: 3 additions & 3 deletions imemo.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ rb_free_tmp_buffer(volatile VALUE *store)
void *ptr = ATOMIC_PTR_EXCHANGE(s->ptr, 0);
long size = s->size;
s->size = 0;
ruby_sized_xfree(ptr, size);
ruby_xfree_sized(ptr, size);
}
}

Expand Down Expand Up @@ -587,7 +587,7 @@ rb_imemo_free(VALUE obj)
if (ci->kwarg) {
((struct rb_callinfo_kwarg *)ci->kwarg)->references--;
if (ci->kwarg->references == 0) {
ruby_sized_xfree((void *)ci->kwarg, rb_callinfo_kwarg_bytes(ci->kwarg->keyword_len));
ruby_xfree_sized((void *)ci->kwarg, rb_callinfo_kwarg_bytes(ci->kwarg->keyword_len));
}
}
RB_DEBUG_COUNTER_INC(obj_imemo_callinfo);
Expand Down Expand Up @@ -637,7 +637,7 @@ rb_imemo_free(VALUE obj)

break;
case imemo_tmpbuf:
ruby_sized_xfree(((rb_imemo_tmpbuf_t *)obj)->ptr, ((rb_imemo_tmpbuf_t *)obj)->size);
ruby_xfree_sized(((rb_imemo_tmpbuf_t *)obj)->ptr, ((rb_imemo_tmpbuf_t *)obj)->size);
RB_DEBUG_COUNTER_INC(obj_imemo_tmpbuf);

break;
Expand Down
Loading