Issue #19538 has been reported by byroot (Jean Boussier).
----------------------------------------
Feature #19538: Performance warnings
https://bugs.ruby-lang.org/issues/19538
* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Suggested by @Eregon.
There are program behaviors that are supported, but that we know aren't good for performance, however it's hard for users to know about them.
Now that we have warning categories, we could add a `:performance` category to allow the VM to emit warning in some situations.
The category would be disabled by default, and users interested in optimizing their program could turn it on in development.
```ruby
Warning[:performance] = true
```
--
https://bugs.ruby-lang.org/
Issue #18885 has been updated by ioquatix (Samuel Williams).
Looking forward to using this.
----------------------------------------
Feature #18885: End of boot advisory API for RubyVM
https://bugs.ruby-lang.org/issues/18885#change-102756
* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
### Context
Many optimizations in the Ruby VM rely on lazily computed caches: Strings coderange, constant caches, method caches, etc etc.
As such even without JIT, some operations need a bit of a warm up, and might be flushed if new constants are defined, new code is loaded, or some objects are mutated.
Additionally these lazily computed caches can cause increased memory usage for applications relying on Copy-on-Write memory.
Whenever one of these caches is updated post fork, the entire memory page is invalidated. Precomputing these caches at the end of boot,
even if based on heuristic, could improve Copy-on-Write performance.
The classic example is the objects generation, young objects must be promoted to the old generation before forking, otherwise they'll get invalidated on the next GC run. That's what https://github.com/ko1/nakayoshi_fork addresses.
But there are other sources of CoW invalidation that could be addressed by MRI if it had a clear notification when it needs to be done.
### Proposal
If applications had an API to notify the virtual machine that they're done loading code and are about to start processing user input,
it would give the VM a good point in time to perform optimizations on the existing code and objects.
e.g. could be something like `RubyVM.prepare`, or `RubyVM.ready`.
It's somewhat similar to [Matz's static barrier idea from RubyConf 2020](https://youtu.be/JojpqfaPhjI?t=1908), except that it wouldn't disable any feature.
### Potential optimizations
`nakayoshi_fork` already does the following:
- Do a major GC run to get rid of as many dangling objects as possible.
- Promote all surviving objects to the highest generation
- Compact the heap.
But it would be much simpler to do this from inside the VM rather than do cryptic things such as `4.times { GC.start }` from the Ruby side.
It's also not good to do this on every fork, once you fork the first long lived child, you shouldn't run it again. So decorating `fork` is not a good hook point.
Also after discussing with @jhawthorn, @tenderlovemaking and @alanwu, we believe this would open the door to several other CoW optimizations:
#### Precompute inline caches
Even though we don't have hard data to prove it, we are convinced that a big source of CoW invalidation are inline caches. Most ISeq are never invoked during initialization, so child processed are forked with mostly cold caches. As a result the first time a method is executed in the child, many memory pages holding ISeq are invalidated as caches get updated.
We think MRI could try to precompute these caches before forking children. Constant cache particularly should be resolvable statically see https://github.com/ruby/ruby/pull/6187.
Method caches are harder to resolve statically, but we can probably apply some heuristics to at least reduce the cache misses.
#### Copy on Write aware GC
We could also keep some metadata about which memory pages are shared, or even introduce a "permanent" generation. [The Instagram engineering team introduced something like that in Python](https://instagram-engineering.com/copy-on-write-friendly-python-gar… ([ticket](https://bugs.python.org/issue31558), [PR](https://github.com/python/cpython/pull/3705)).
That makes the GC aware of which objects live on a shared page. With this information the GC can decide to no free dangling objects leaving on these pages, not to compact these pages, etc.
#### Scan the coderange of all strings
Strings have a lazily computed `coderange` attribute in their flags. So if a string is allocated at boot, but only used after fork, on first use its coderange will mayneed to be computed and the string mutated.
Using https://github.com/ruby/ruby/pull/6076, I noticed that 58% of the strings retained at the end of the boot sequence had an `UNKNOWN` coderange.
So eagerly scanning the coderange of all strings could also improve Copy on Write performance.
#### malloc_trim
This hook will also be a good point to release unused pages to the system with `malloc_trim`.
--
https://bugs.ruby-lang.org/
Issue #18726 has been updated by shyouhei (Shyouhei Urabe).
Status changed from Open to Closed
Let me close this. Clang-15 + C2X combination in our CI is stable now. If anything please reopen.
----------------------------------------
Misc #18726: CI Error on c99 and c2x
https://bugs.ruby-lang.org/issues/18726#change-102751
* Author: znz (Kazuhiro NISHIYAMA)
* Status: Closed
* Priority: Normal
* Assignee: shyouhei (Shyouhei Urabe)
----------------------------------------
https://github.com/ruby/ruby/runs/6013849896?check_suite_focus=true
```
checking char bit... 8
checking size of int... 0
checking size of short... 0
checking size of long... 0
configure: error: in `/__w/ruby/ruby/build':
configure: error: cannot compute sizeof (long long)
See `config.log' for more details
checking size of long long...
Error: Process completed with exit code 77.
```
I investigate it, the cause is that autoconf is old in `ghcr.io/ruby/ruby-ci-image:clang-15`. (Autoconf 2.69)
Autoconf 2.71 generates with `void`.
How to reproduce:
```
% docker run --rm -it ghcr.io/ruby/ruby-ci-image:clang-15
$ sudo apt update
$ sudo apt install git
$ git clone --depth=1 https://github.com/ruby/ruby $HOME/src
$ mkdir $HOME/build
$ cd $HOME/build
$ ../src/autogen.sh
$ ../src/configure -C --enable-debug-env --disable-install-doc --with-ext=-test-/cxxanyargs,+ --without-valgrind --without-jemalloc --without-gmp --with-gcc="clang-15 -std=c99 -Werror=pedantic -pedantic-errors" --enable-shared optflags=-O1 debugflags=-ggdb3
```
Tail of configure output:
```
checking char bit... 8
checking size of int... 0
checking size of short... 0
checking size of long... 0
checking size of long long... configure: error: in `/home/ci/build':
configure: error: cannot compute sizeof (long long)
See `config.log' for more details
```
Quote from config.log:
```
configure:13939: checking size of int
configure:13944: clang-15 -std=c99 -Werror=pedantic -pedantic-errors -o conftest -O1 -fno-fast-math -ggdb3 -fdeclspec -fstack-protector-strong conftest.c -lm >&5
conftest.c:107:25: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
static long int longval () { return (long int) (sizeof (int)); }
^
void
conftest.c:108:35: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
static unsigned long int ulongval () { return (long int) (sizeof (int)); }
^
void
2 errors generated.
```
--
https://bugs.ruby-lang.org/
Issue #19525 has been reported by mame (Yusuke Endoh).
----------------------------------------
Misc #19525: DevMeeting-2023-04-13
https://bugs.ruby-lang.org/issues/19525
* Author: mame (Yusuke Endoh)
* Status: Open
* Priority: Normal
----------------------------------------
# The next dev meeting
**Date: 2023/04/13 13:00-17:00** (JST)
Log: *TBD*
- Dev meeting *IS NOT* a decision-making place. All decisions should be done at the bug tracker.
- Dev meeting is a place we can ask Matz, nobu, nurse and other developers directly.
- Matz is a very busy person. Take this opportunity to ask him. If you can not attend, other attendees can ask instead of you (if attendees can understand your issue).
- We will write a record of the discussion in the file or to each ticket in English.
- All activities are best-effort (keep in mind that most of us are volunteer developers).
- The date, time and place of the meeting are scheduled according to when/where we can reserve Matz's time.
- *DO NOT* discuss then on this ticket, please.
# Call for agenda items
If you have a ticket that you want matz and committers to discuss, please post it into this ticket in the following format:
```
* [Ticket ref] Ticket title (your name)
* Comment (A summary of the ticket, why you put this ticket here, what point should be discussed, etc.)
```
Example:
```
* [Feature #14609] `Kernel#p` without args shows the receiver (ko1)
* I feel this feature is very useful and some people say :+1: so let discuss this feature.
```
- It is recommended to add a comment by 2023/04/10. We hold a preparatory meeting to create an agenda a few days before the dev-meeting.
- The format is strict. We'll use [this script to automatically create an markdown-style agenda](https://gist.github.com/mame/b0390509ce1491b43610b9ebb665eb86). We may ignore a comment that does not follow the format.
- Your comment is mandatory. We cannot read all discussion of the ticket in a limited time. We appreciate it if you could write a short summary and update from a previous discussion.
--
https://bugs.ruby-lang.org/
Issue #19573 has been reported by jeremyevans0 (Jeremy Evans).
----------------------------------------
Feature #19573: Add Class#singleton_inherited
https://bugs.ruby-lang.org/issues/19573
* Author: jeremyevans0 (Jeremy Evans)
* Status: Open
* Priority: Normal
----------------------------------------
This would be similar to `Class#inherited`, but would be called with singleton classes of instances instead of subclasses. This could be used to warn or raise on singleton class creation, or modify the instance to change behavior, such as allow optimizations when a singleton class does not exist, but allow fallbacks if it does exist.
```ruby
c = Class.new do
def self.inherited(subclass)
p :inherited
end
def self.singleton_inherited(singleton_class)
# could use singleton_class.attached_object for modifying related object
p :singleton_inherited
end
end
Class.new(c)
# prints :inherited
c.new.singleton_class
# prints :singleton_inherited
```
This could potentially be an instance method (e.g. `Kernel#singleton_class_created` or `BasicObject#singleton_class_created`) instead of a class method. However, that would not grant any additional flexibility, since per-object behavior first requires creation of a singleton class.
If this is accepted, should the method be called for singleton classes created by `Kernel#clone` if the receiver has a singleton class? I think it should, as `Class#inherited` is called for `Class#clone`.
--
https://bugs.ruby-lang.org/
Issue #19331 has been reported by Kulikjak (Jakub Kulik).
----------------------------------------
Bug #19331: --enable-rpath results in incorrect RPATH in Ruby 3.1.3
https://bugs.ruby-lang.org/issues/19331
* Author: Kulikjak (Jakub Kulik)
* Status: Open
* Priority: Normal
* ruby -v: 3.1.3
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
I just updated Ruby from 3.1.2 to 3.1.3 and found out that all .so libraries from the enc directory have wrong RPATH/RUNPATH (when building with `--enable-rpath`). I first hit this on Solaris, but my testing on Linux resulted in the same thing. It can be easily reproduced with the following:
```
wget http://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.3.tar.gz
tar xzf ruby-3.1.3.tar.gz
cd ruby-3.1.3
./configure --prefix=/usr/ruby/3.1 --mandir=/usr/ruby/3.1/share/man --bindir=/usr/ruby/3.1/bin --sbindir=/usr/ruby/3.1/sbin --libdir=/usr/ruby/3.1/lib/amd64 --with-rubylibprefix=/usr/ruby/3.1/lib/ruby --enable-shared --enable-rpath
/usr/bin/make -j 16 -l 32
objdump -x ./.ext/x86_64-linux/enc/windows_31j.so | grep RPATH
```
While previously this resulted in the following output:
`RPATH /usr/ruby/3.1/lib/amd64`
in 3.1.3 it is wrongly set to the build directory:
`RPATH /home/jkulik/rubytest/ruby-3.1.3`
I tried looking for some obvious change but didn't find the core of this issue yet. All I found out is that generated `enc.mk` differs in `prefix` and `libdir`
```
-prefix = /usr/ruby/3.1
+prefix = /home/jkulik/rubytest/ruby-3.1.3
exec_prefix = $(prefix)
-libdir = $(exec_prefix)/lib/amd64
+libdir = /home/jkulik/rubytest/ruby-3.1.3
```
`rbconfig.rb` is similar in both versions, but when I print out `CONFIG` in `make_encmake.rb` right after `load File.expand_path("lib/mkmf.rb", dir)`, I can see the differences from above, so it's probably something in the `lib/mkmf.rb` file that changes that.
I am seeing the same issue in the current latest ruby 3.1 branch cloned from github.
--
https://bugs.ruby-lang.org/
Issue #19590 has been reported by nobu (Nobuyoshi Nakada).
----------------------------------------
Feature #19590: Include the invalid argument in error messages from `Process.clock_gettime` and `Process.clock_getres`
https://bugs.ruby-lang.org/issues/19590
* Author: nobu (Nobuyoshi Nakada)
* Status: Open
* Priority: Normal
----------------------------------------
The argument of `Process.clock_gettime` and `Process.clock_getres` is complex a little, it supports `Integer` and `Symbol` which are platform dependent.
In most cases, available clocks are defined as constants under `Process`, but on some platforms (MinGW at least) some constants are defined but fails with `EINVAL`, and the exception doesn't tell what was wrong.
```shell-session
$ ./ruby --disable=gems -v -e 'Process.constants.grep(/\ACLOCK_/).each {|c| clk = Process.const_get(c); p [c, clk, (Process.clock_gettime(clk) rescue $!)]}'
ruby 3.3.0dev (2023-02-23T18:13:13Z master 1fdaa06660) [x64-mingw-ucrt]
[:CLOCK_REALTIME_COARSE, 4, #<Errno::EINVAL: Invalid argument - clock_gettime>]
[:CLOCK_REALTIME, 0, 1681206710.103821]
[:CLOCK_MONOTONIC, 1, 167731.5111065]
[:CLOCK_PROCESS_CPUTIME_ID, 2, #<Errno::EINVAL: Invalid argument - clock_gettime>]
[:CLOCK_THREAD_CPUTIME_ID, 3, #<Errno::EINVAL: Invalid argument - clock_gettime>]
```
And it wastes time when passing a `Symbol` with typo.
So my proposal is to add the argument to the exception message.
```shell-session
$ ./miniruby -e 'p Process.clock_gettime(:CLOCK_BASED_CLOCK_PROCESS_CPUTIME)'
-e:1:in `clock_gettime': Invalid argument - clock_gettime(:CLOCK_BASED_CLOCK_PROCESS_CPUTIME) (Errno::EINVAL)
from -e:1:in `<main>'
```
--
https://bugs.ruby-lang.org/