2445 Commits

Author SHA1 Message Date
Nobuyoshi Nakada
28b0e5125f [Bug #18433] Remove unneeded declaration
This `rb_cObject` declaration was only for `rb_cData()` that was
removed at 7c738ce5e649b82bdc1305d5c347e81886ee759a.
2026-01-05 16:47:14 +09:00
Peter Zhu
6939f03f4c Add field handle_weak_references to TypedData
This commit adds a field handle_weak_references to rb_data_type_struct for
the callback when handling weak references. This avoids TypedData objects
from needing to expose their rb_data_type_struct and weak references function.
2026-01-04 09:02:40 -05:00
Nobuyoshi Nakada
ea05c23ee8 Extract RBIMPL_TYPEDDATA_PRECONDITION 2026-01-01 10:00:33 +09:00
Nobuyoshi Nakada
094145fbc1
[DOC] Move typed-data related macros
The flags for `rb_data_type_t::flags` are public constants for
defining `rb_data_type_t`.  The embedded data flag and mask are
internal implementation detail.
2025-12-31 17:54:42 +09:00
Nobuyoshi Nakada
d95bebe06c
Make RTYPEDDATA_EMBEDDABLE_P internal-use only
It should not be exposed because it is so implementation specific that
it is only used in gc.c even within the entire Ruby source tree.
2025-12-31 11:29:29 +09:00
Nobuyoshi Nakada
26088dcd4a
[DOC] State that rb_unexpected_type is private 2025-12-29 18:41:58 +09:00
Nobuyoshi Nakada
56a6a21f28
Return NULL in a void * function 2025-12-29 18:40:48 +09:00
Nobuyoshi Nakada
0f64da9672
Make rb_check_typeddata and rbimpl_check_typeddata identical 2025-12-29 18:40:47 +09:00
Nobuyoshi Nakada
72627d85e3
Declare rb_data_typed_t parameters and return values as nonull 2025-12-29 18:20:36 +09:00
Nobuyoshi Nakada
cb01b9023e
rtypeddata.h: Add missing RBIMPL_CAST
In public headers, casts should be enclosed in `RBIMPL_CAST` for
compilation in C++.
2025-12-29 10:33:31 +09:00
Nobuyoshi Nakada
68cd46353c
Ensure T_DATA before RTYPEDDATA_P
For the precondition of `RTYPEDDATA_P` that the argument must be a
Ruby object of `::RUBY_T_DATA`.
2025-12-29 02:01:12 +09:00
Nobuyoshi Nakada
c342461582
Remove an useless macro definition RSTRUCT_PTR
The underlying definition, `rb_struct_ptr`, was removed four years
ago.
2025-12-26 19:33:03 +09:00
Nobuyoshi Nakada
8c7b1401a5
Remove rb_iterate deprecated since 1.9 2025-12-26 17:53:23 +09:00
Nobuyoshi Nakada
2ac4cc0a1b
Remove RUBY_FL_DUPPED deprecated for 4 years 2025-12-26 17:53:23 +09:00
Nobuyoshi Nakada
a3ac83b7b8
Remove taintedness/trustedness enums/macros deprecated for 4 years 2025-12-26 17:53:22 +09:00
Nobuyoshi Nakada
a447d39da2
Remove rb_gc_force_recycle deprecated as "removed soon" 2025-12-26 17:02:42 +09:00
Nobuyoshi Nakada
cf60dc2642
Remove rb_clone_setup and rb_dup_setup deprecated for 4 years 2025-12-26 17:02:42 +09:00
Nobuyoshi Nakada
a41b154029
Remove rb_complex_polar deprecated for 7 years 2025-12-26 17:02:42 +09:00
Nobuyoshi Nakada
f84110e601
Remove old APIs to allocate a data object deprecated for 5 years 2025-12-26 17:02:41 +09:00
Nobuyoshi Nakada
5c2f6639c5
Remove rb_clear_constant_cache deprecated for 3 years 2025-12-26 16:48:16 +09:00
Nobuyoshi Nakada
4c07e61bc9
Deprecate old VC 2025-12-26 15:11:23 +09:00
Yukihiro "Matz" Matsumoto
010dcf8556
Development of 4.1.0 started. 2025-12-26 08:59:23 +09:00
Peter Zhu
10b97f52fd Implement declaring weak references
[Feature #21084]

 # Summary

The current way of marking weak references uses `rb_gc_mark_weak(VALUE *ptr)`.
This presents challenges because Ruby's GC is incremental, meaning that if the
`ptr` changes (e.g. realloc'd or free'd), then we could have an invalid memory
access. This also overwrites `*ptr = Qundef` if `*ptr` is dead, which prevents
any cleanup to be run (e.g. freeing memory or deleting entries from hash
tables). This ticket proposes `rb_gc_declare_weak_references` which declares
that an object has weak references and calls a cleanup function after marking,
allowing the object to clean up any memory for dead objects.

 # Introduction

In [[Feature #19783]](https://bugs.ruby-lang.org/issues/19783), I introduced an
API allowing objects to mark weak references, the function signature looks like
this:

```c
void rb_gc_mark_weak(VALUE *ptr);
```

`rb_gc_mark_weak` is called during the marking phase of the GC to specify that
the memory at `ptr` holds a pointer to a Ruby object that is weakly referenced.
`rb_gc_mark_weak` appends this pointer to a list that is processed after the
marking phase of the GC. If the object at `*ptr` is no longer alive, then it
overwrites the object reference with a special value (`*ptr = Qundef`).

However, this API resulted in two challenges:

1. Ruby's default GC is incremental, which means that the GC is not ran in one
   phase, but rather split into chunks of work that interleaves with Ruby
   execution. The `ptr` passed into `rb_gc_mark_weak` could be on the malloc
   heap, and that memory could be realloc'd or even free'd. We had to use
   workarounds such as `rb_gc_remove_weak` to ensure that there were no illegal
   memory accesses. This made `rb_gc_mark_weak` difficult to use, impacted
   runtime performance, and increased memory usage.
2. When an object dies, `rb_gc_mark_weak` only overwites the reference with
   `Qundef`. This means that if we want to do any cleanup (e.g. free a piece of
   memory or delete a hash table entry), we could not do that and had to defer
   this process elsewhere (e.g. during marking or runtime).

In this ticket, I'm proposing a new API for weak references. Instead of an
object marking its weak references during the marking phase, the object declares
that it has weak references using the `rb_gc_declare_weak_references` function.
This declaration occurs during runtime (e.g. after the object has been created)
rather than during GC.

After an object declares that it has weak references, it will have its callback
function called after marking as long as that object is alive. This callback
function can then call a special function `rb_gc_handle_weak_references_alive_p`
to determine whether its references are alive. This will allow the callback
function to do whatever it wants on the object, allowing it to perform any
cleanup work it needs.

This significantly simplifies the code for `ObjectSpace::WeakMap` and
`ObjectSpace::WeakKeyMap` because it no longer needs to have the workarounds for
the limitations of `rb_gc_mark_weak`.

 # Performance

The performance results below demonstrate that `ObjectSpace::WeakMap#[]=` is now
about 60% faster because the implementation has been simplified and the number
of allocations has been reduced. We can see that there is not a significant
impact on the performance of `ObjectSpace::WeakMap#[]`.

Base:

```
ObjectSpace::WeakMap#[]=
                          4.620M (± 6.4%) i/s  (216.44 ns/i) -     23.342M in   5.072149s
ObjectSpace::WeakMap#[]
                         30.967M (± 1.9%) i/s   (32.29 ns/i) -    154.998M in   5.007157s
```

Branch:

```
ObjectSpace::WeakMap#[]=
                          7.336M (± 2.8%) i/s  (136.31 ns/i) -     36.755M in   5.013983s
ObjectSpace::WeakMap#[]
                         30.902M (± 5.4%) i/s   (32.36 ns/i) -    155.901M in   5.064060s
```

Code:

```
require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "benchmark-ips"
end

wmap = ObjectSpace::WeakMap.new
key = Object.new
val = Object.new
wmap[key] = val

Benchmark.ips do |x|
  x.report("ObjectSpace::WeakMap#[]=") do |times|
    i = 0
    while i < times
      wmap[Object.new] = Object.new
      i += 1
    end
  end

  x.report("ObjectSpace::WeakMap#[]") do |times|
    i = 0
    while i < times
      wmap[key]
      wmap[val] # does not exist
      i += 1
    end
  end
end
```

 # Alternative designs

Currently, `rb_gc_declare_weak_references` is designed to be an internal-only
API. This allows us to assume the object types that call
`rb_gc_declare_weak_references`. In the future, if we want to open up this API
to third parties, we may want to change this function to something like:

```c
void rb_gc_add_cleaner(VALUE obj, void (*callback)(VALUE obj));
```

This will allow the third party to implement a custom `callback` that gets
called after the marking phase of GC to clean up any dead references. I chose
not to implement this design because it is less efficient as we would need to
store a mapping from `obj` to `callback`, which requires extra memory.
2025-12-25 09:18:17 -05:00
Jean Boussier
8cf4f373ff thread_sync.c: declare queue_data_type as parent of szqueue_data_type.
Allows to remove some duplicated code like szqueue_length, etc.
2025-12-18 20:57:05 +01:00
Nobuyoshi Nakada
b816f7bac5
[DOC] Fix documents of rb_intern_str and so on
* `rb_intern_str`: the argument must be `T_STRING`, no conversion.

* `rb_intern_str`, `rb_check_id`, `rb_to_id`, `rb_check_symbol`: raise
  `EncodingError` unless the "name" argument is a valid string in its
  encoding.
2025-12-18 11:27:05 +09:00
Nobuyoshi Nakada
f2d2a757d1
[DOC] Re-fill the paragraph 2025-12-18 10:14:40 +09:00
Augustin Gottlieb
cfa3e7cf75
[DOC] Fix double-word typos in comments
Found via `grep` for repeated words.

* set.c: Fix "or or"
* include/ruby/internal/symbol.h: Fix "is is"
* include/ruby/internal/ctype.h: Fix "in in"
2025-12-18 09:34:32 +09:00
Nobuyoshi Nakada
61bab18890 Rename to struct rbimpl_size_overflow_tag
This struct is used for addition not only for multiplication, so
remove the word `mul`, and make the member names more descriptive.
2025-12-17 17:35:58 +09:00
Jean Boussier
094418a6de gc.h: Reintroduce immediate guard in rb_obj_written
This guard was removed in https://github.com/ruby/ruby/pull/13497
on the justification that some GC may need to be notified even for
immediate.

But the two currently available GCs don't, and there are plenty
of assumtions GCs don't everywhere, notably in YJIT and ZJIT.

This optimization is also not so micro (but not huge either).
I routinely see 1-2% wasted there on micro-benchmarks.

So perhaps if in the future we actually need this, it might make
sense to introduce a way for GCs to declare that as an option,
but in the meantime it's extra overhead with little gain.
2025-12-16 21:00:27 +01:00
Benoit Daloze
b423204cb3 Fix documentation of RB_PASS_CALLED_KEYWORDS in C API 2025-12-13 21:09:05 +01:00
Luke Gruber
3add3db797
Fewer calls to GET_EC() and GET_THREAD() (#15506)
The changes are to `io.c` and `thread.c`.
I changed the API of 2 exported thread functions from `internal/thread.h` that
didn't look like they had any use in C extensions:

* rb_thread_wait_for_single_fd
* rb_thread_io_wait

I didn't change the following exported internal function because it's
used in C extensions:

* rb_thread_fd_select

I added a comment to note that this function, although internal, is used
in C extensions.
2025-12-12 14:47:43 -05:00
Nobuyoshi Nakada
5541c0d896 Win32: Make rb_w32_osid return Windows NT always
Since support for Windows 9x was dropped over a decade ago.
2025-12-12 14:24:03 +09:00
Nobuyoshi Nakada
f939f0433a Win32: Deprecate Windows version info API
`dwMajorVersion` alone has no meaning since Windows 7.  Use API in
VersionHelper.h instead.
2025-12-12 14:24:03 +09:00
Nobuyoshi Nakada
3636277dc5
Add NUM2PTR and PTR2NUM macros
These macros have been defined here and there, so collect them.
2025-12-10 12:09:50 +09:00
Jean Boussier
98390d9360 Don't declare rbimpl_check_typeddata as pure
[Bug #21771]

It may raise so it's incorrect and can lead to the compiler
optimizing the call out.
2025-12-09 18:08:00 +01:00
Nobuyoshi Nakada
e61b79b384
Fix a typo in the deprecation warning message 2025-12-09 02:16:45 +09:00
Kazuki Yamaguchi
be882278f2 Move RBIMPL_ATTR_DEPRECATED_* macros to the appropriate header file
Move these macros from include/ruby/backward.h to
include/ruby/internal/attr/deprecated.h, alongside the other similar
macros.

include/ruby/internal/intern/vm.h cannot currently use them because
include/ruby/backward.h is included too late.
2025-12-08 11:47:39 +09:00
Samuel Williams
42f5654b69
Yield to scheduler if interrupts are pending. (#14700) 2025-12-06 21:44:14 +13:00
Koichi Sasada
2aaea665bb fix typo s/sharable/shareable/ 2025-12-05 03:10:50 +09:00
Koichi Sasada
f2cd772329 (experimental) RUBY_TYPED_FROZEN_SHAREABLE_NO_REC
`T_DATA` has a flag `RUBY_TYPED_FROZEN_SHAREABLE` which means
if the `T_DATA` object is frozen, it can be sharable.
On the `Ractor.make_sharable(obj)`, rechable objects from the
`T_DATA` object will be apply `Ractor.make_shareable` recursively.

`RUBY_TYPED_FROZEN_SHAREABLE_NO_REC` is similar to the
`RUBY_TYPED_FROZEN_SHAREABLE`, but doesn't apply `Ractor.make_sharable`
recursively for children.
If it refers to unshareable objects, it will simply raise an error.

I'm not sure this pattern is common or not, so it is not in public.
If we find more cases, we can discuss publication.
2025-12-05 02:28:30 +09:00
Nobuyoshi Nakada
b872fbe3dd
Deprecate rb_eval_cmd_kw 2025-12-04 18:07:49 +09:00
Jean Boussier
fcf3939780 Speedup TypedData_Get_Struct
While profiling `Monitor#synchronize` and `Mutex#synchronize`
I noticed a fairly significant amount of time spent in
`rb_check_typeddata`.

By implementing a fast path that assumes the object is valid
and that can be inlined, it does make a significant difference:

Before:

```
  Mutex     13.548M (± 3.6%) i/s   (73.81 ns/i) -     68.566M in   5.067444
Monitor     10.497M (± 6.5%) i/s   (95.27 ns/i) -     52.529M in   5.032698s
```

After:

```
  Mutex     20.887M (± 0.3%) i/s   (47.88 ns/i) -    106.021M in   5.075989s
Monitor     16.245M (±13.3%) i/s   (61.56 ns/i) -     80.705M in   5.099680s
```

```ruby
require 'bundler/inline'

gemfile do
  gem "benchmark-ips"
end

mutex = Mutex.new
require "monitor"
monitor = Monitor.new

Benchmark.ips do |x|
  x.report("Mutex") { mutex.synchronize { } }
  x.report("Monitor") { monitor.synchronize { } }
end
```
2025-12-03 17:54:27 +01:00
Peter Zhu
404e6aa9b5 [DOC] Fix typo in rb_debug_inspector_current_depth 2025-11-27 18:23:56 -08:00
Nobuyoshi Nakada
7743123551 Win32: Drop support for older than MSVC 12.0/_MSC_VER 1800
Visual C++ 2013 (12.0):
- _MSC_VER: 1800
- MSVCRT_VERSION: 120
2025-11-19 11:03:42 +09:00
Nobuyoshi Nakada
cdb9893c55 Win32: Drop support for older than MSVC 8.0/_MSC_VER 1400
Visual C++ 2005 (8.0):
- _MSC_VER: 1400
- MSVCRT_VERSION: 80
2025-11-19 11:03:42 +09:00
nagachika
48dce7874f simplify RSRING_GETMEM() definition. 2025-11-11 18:57:30 +09:00
nagachika
367ddd445c include/ruby/internal/core/rstring.h: Remove rbimpl_rstring_getmem() definition. 2025-11-11 18:57:30 +09:00
nagachika
9d44cb0b2b Remove rbimpl_rstring_getmem() usage as workaround for GCC 15.2.1 optimization bug. [Bug #21655] 2025-11-11 18:57:30 +09:00
Earlopain
a2201570bd Remove rb_path_check declaration
Implementation was removed in a4c051b870
2025-11-07 23:35:51 +09:00
Yukihiro "Matz" Matsumoto
6d81969b47
Development of 4.0.0 started. 2025-11-07 16:41:47 +09:00