Thread::Queue spends a significant amount of time in array functions,
checking for invariants we know aren't a problem, and whether the backing
array need to reordered.
By using a ring buffer we can remove a lot of overhead (~23% faster).
```
$ hyperfine './miniruby --yjit /tmp/q.rb' './miniruby-qrb --yjit /tmp/q.rb'
Benchmark 1: ./miniruby --yjit /tmp/q.rb
Time (mean ± σ): 1.050 s ± 0.191 s [User: 0.988 s, System: 0.004 s]
Range (min … max): 0.984 s … 1.595 s 10 runs
Benchmark 2: ./miniruby-qrb --yjit /tmp/q.rb
Time (mean ± σ): 844.2 ms ± 3.1 ms [User: 840.4 ms, System: 2.8 ms]
Range (min … max): 838.6 ms … 848.9 ms 10 runs
Summary
./miniruby-qrb --yjit /tmp/q.rb ran
1.24 ± 0.23 times faster than ./miniruby --yjit /tmp/q.rb
```
```
q = Queue.new([1, 2, 3, 4, 5, 6, 7, 8])
i = 2_000_000
while i > 0
i -= 1
q.push(q.pop)
q.push(q.pop)
q.push(q.pop)
q.push(q.pop)
q.push(q.pop)
q.push(q.pop)
q.push(q.pop)
q.push(q.pop)
q.push(q.pop)
q.push(q.pop)
end
```
A plain `char` may be `signed` or `unsigned` depending on the
implementation. Also, bitwise ORing of `signed` values is not
guaranteed to be `signed`. To ensure portability, should logical-OR
each comparison, but casting to `signed char` is usually sufficient.
https://github.com/ruby/json/commit/8ad744c532
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.
Fixes issue pointed out in https://bugs.ruby-lang.org/issues/21084#note-7.
The following script crashes:
wmap = ObjectSpace::WeakMap.new
GC.disable # only manual GCs
GC.start
GC.start
retain = []
50.times do
k = Object.new
wmap[k] = true
retain << k
end
GC.start # wmap promoted, other objects still young
retain.clear
GC.start(full_mark: false)
wmap.keys.each(&:itself) # call method on keys to cause crash
* Consistent with plain `blocks` and `for` blocks and methods
where the source_location covers their entire definition.
* Matches the documentation which mentions
"where the definition starts/ends".
* Partially reverts d357d50f0a74409446f4cccec78593373f5adf2f
which was a workaround to be compatible with parse.y.
* This reverts commit 065c48cdf11a1c4cece84db44ed8624d294f8fd5.
* This functionality is very valuable and has already taken 14 years
to agree on the API.
* Let's just document it's byte columns (in the next commit).
* See https://bugs.ruby-lang.org/issues/21783#note-9
Without this change, classes (including iclass) are allocated
as un-boxable classes after initializing user boxes (after starting
script evaluation). Under this situation, iclasses are created as
un-boxabled class when core modules are included by a class in the
root box, then it causes problems because it's in the root box but
it can't have multiple classexts.
This change makes it possible to allocate boxable classes even after
initializing user boxes. Classes create in the root box will be
boxable, and those can have 2 or more classexts.
This commit adds an `expect1_opening` function that expects a token and
attaches the error to the opening token location rather than the current
position. This is useful for errors about missing closing tokens, where
we want to point to the line with the opening token rather than the end
of the file.
For example:
```ruby
def foo
def bar
def baz
^ expected an `end` to close the `def` statement
^ expected an `end` to close the `def` statement
^ expected an `end` to close the `def` statement
```
This would previously produce three identical errors at the end of the
file. After this commit, they would be reported at the opening token
location:
```ruby
def foo
^~~ expected an `end` to close the `def` statement
def bar
^~~ expected an `end` to close the `def` statement
def baz
^~~ expected an `end` to close the `def` statement
```
I considered using the end of the line where the opening token is
located, but in some cases that would be less useful than the opening
token location itself. For example:
```ruby
def foo def bar def baz
```
Here the end of the line where the opening token is located would be the
same for each of the unclosed `def` nodes.
https://github.com/ruby/prism/commit/2d7829f060
`ALLOCA` with too large size may result in stack overflow.
Incidentally, this suppresses the GCC false maybe-uninitialized
warning in `product_each`.
Also shrink `struct product_state` when `sizeof(int) < sizeof(VALUE)`.
Fixes the following compiler warnings:
random.c: In function `random_init`:
random.c:416:38: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized]
416 | unsigned int major = rng->version.major;
| ~~~~~~~~~~~~^~~~~~
random.c: In function `random_bytes`:
random.c:1284:8: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized]
1284 | rng->get_bytes(rnd, ptr, n);
| ~~~^~~~~~~~~~~
random.c:1299:34: note: `rng` was declared here
1299 | const rb_random_interface_t *rng;
| ^~~
random.c: In function `rand_random_number`:
random.c:1606:12: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized]
1606 | return rand_range(obj, rng, rnd, vmax);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
random.c:1624:34: note: `rng` was declared here
1624 | const rb_random_interface_t *rng;
| ^~~
random.c: In function `random_rand`:
random.c:1120:15: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized]
1120 | return rng->get_int32(rnd);
| ~~~^~~~~~~~~~~
random.c:1573:34: note: `rng` was declared here
1573 | const rb_random_interface_t *rng;
| ^~~