* Rewrite Kernel#tap with Ruby
This was good for VM too, but of course my intention is to unblock JIT's inlining of a block over yield
(inlining invokeyield has not been committed though).
* Fix test_settracefunc
About the :tap deletions, the :tap events are actually traced (we already have a TracePoint test for builtin methods),
but it's filtered out by tp.path == "xyzzy" (it became "<internal:kernel>"). We could trace tp.path == "<internal:kernel>"
cases too, but the lineno is impacted by kernel.rb changes and I didn't want to make it fragile for kernel.rb lineno changes.
Use ID instead of GENTRY for gvars.
Global variables are compiled into GENTRY (a pointer to struct
rb_global_entry). This patch replace this GENTRY to ID and
make the code simple.
We need to search GENTRY from ID every time (st_lookup), so
additional overhead will be introduced.
However, the performance of accessing global variables is not
important now a day and this simplicity helps Ractor development.
* RUBY_DEBUG_LOG: Logging debug information mechanism
This feature provides a mechanism to store logging information
to a file, stderr or memory space with simple macros.
The following information will be stored.
* (1) __FILE__, __LINE__ in C
* (2) __FILE__, __LINE__ in Ruby
* (3) __func__ in C (message title)
* (4) given string with sprintf format
* (5) Thread number (if multiple threads are running)
This feature is enabled only USE_RUBY_DEBUG_LOG is enabled.
Release version should not enable it.
Running with the `RUBY_DEBUG_LOG` environment variable enables
this feature.
# logging into a file
RUBY_DEBUG_LOG=/path/to/file STDERR
# logging into STDERR
RUBY_DEBUG_LOG=stderr
# logging into memory space (check with a debugger)
# It will help if the timing is important.
RUBY_DEBUG_LOG=mem
RUBY_DEBUG_LOG_FILTER environment variable can specify the fileter string.
If "(3) __func__ in C (message title)" contains the specified string, the
infomation will be stored (example: RUBY_DEBUG_LOG_FILTER=str will enable
only on str related information).
In a MRI source code, you can use the following macros:
* RUBY_DEBUG_LOG(fmt, ...): Above (1) to (4) will be logged.
* RUBY_DEBUG_LOG2(file, line, fmt, ...):
Same as RUBY_DEBUG_LOG(), but (1) will be replaced with given file, line.
When use non-frozen string for hash key with `rb_hash_aset()`, it will duplicate and freeze it internally.
To avoid duplicate and freeze, this patch will give a frozen string in `rb_hash_aset()`.
```
Warming up --------------------------------------
json 14.000 i/100ms
Calculating -------------------------------------
json 148.844 (± 1.3%) i/s - 756.000 in 5.079969s
```
```
Warming up --------------------------------------
json 16.000 i/100ms
Calculating -------------------------------------
json 165.608 (± 1.8%) i/s - 832.000 in 5.025367s
```
```
require 'json'
require 'securerandom'
require 'benchmark/ips'
obj = []
1000.times do |i|
obj << {
"id": i,
"uuid": SecureRandom.uuid,
"created_at": Time.now
}
end
json = obj.to_json
Benchmark.ips do |x|
x.report "json" do |iter|
count = 0
while count < iter
JSON.parse(json)
count += 1
end
end
end
```
https://github.com/flori/json/commit/18292c0c1d
(I was not aware of this because I use clang, but) it seems gcc cannot
detect reachablility of this point. It renders an unused variable
warning, which is a false positive. Let us suppress the compiler.
https://github.com/ruby/ruby/runs/816997191#step:9:62
Not every compilers understand that rb_raise does not return. When a
function does not end with a return statement, such compilers can issue
warnings. We would better tell them about reachabilities.