* Use ffi_closure_free unconditionally.
The current conditionals reflect historic heritage of FFI. Usage of
ffi_closure_free should be better default nowadays, because libffi 3.0.5
fixing issues of ffi_closure_free should be widely available.
* RUBY_LIBFFI_MODVERSION is not used anymore.
Because `ffi_closure_free()` is not used unconditionally, there is no
other use for RUBY_LIBFFI_MODVERSION define, so drop its usage.
* Use more meaningful variable name.
`ver` variable used to be used to pupulate RUBY_LIBFFI_MODVERSION
define. Since the define was removed, the `libffi_dir` variable name
should better describe the remaining usage of the variable.
https://github.com/ruby/fiddle/commit/c49cc79eb8
If the first parameter to Fiddle::Function is a closure object (rather
than an interger), `rb_Integer` will cast it to an integer but not
maintain a reference to the closure. Then if the closure gets GC'd, we
have a segv. This commit keeps a reference to the original parameter to
initialize so that the object will not be GC'd.
Fixes: https://bugs.ruby-lang.org/issues/13286https://github.com/ruby/fiddle/commit/0fc697bbc5
Previously, the type of these arguments were not checked, leading to
NoMethodErrors in some cases, and TypeErrors in other cases, but not
showing what field was having the problems. This change makes it so
the field with the problem is included in the error message.
For the valid_*? methods, this changes them to return false if one
of the arguments that should be numeric is not.
Fixes Ruby Bug 11935
Fixes Ruby Misc 15298
https://github.com/ruby/date/commit/a2f4b665f8
Previously, julian dates would not round trip through to_time.to_date,
because Time is always considered gregorian. This converts the Date
instance from julian to gregorian before converting to Time, ensuring
that an equal date object will be returned if converting that Time
back to Date.
This does result in julian Date objects showing different day values
if converting to Time.
Fixes Ruby Bug 8428.
https://github.com/ruby/date/commit/d8df64555e
Tabs were expanded because previously the file did not have any tab indentation.
Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook.
Delegate MonitorMixin#synchronize body to Monitor#synchronize.
It makes guarantee interrupt safe (because Monitor#synchronize is
written in C). I thought Ruby implementation is also safe, but I
got stuck failure <http://ci.rvm.jp/results/trunk_test@P895/2327639>
so that I introduce this fix to guarantee interrupt safe.
Recent monitor.rb has performance problem because of interrupt
handlers. 'Monitor#synchronize' is frequently used primitive
so the performance of this method is important.
This patch rewrite 'monitor.rb' with 'monitor.so' (C-extension)
and make it faster. See [Feature #16255] for details.
Monitor class objects are normal object which include MonitorMixin.
This patch introduce a Monitor class which is implemented on C
and MonitorMixin uses Monitor object as re-entrant (recursive)
Mutex. This technique improve performance because we don't need
to care atomicity and we don't need accesses to instance variables
any more on Monitor class.
In where to convert Hash key to String for json, this patch will add shortcut for String/Symbol in Hash key.
```
$ ruby bench_json_generate.rb
Warming up --------------------------------------
json 65.000 i/100ms
Calculating -------------------------------------
json 659.576 (± 1.5%) i/s - 3.315k in 5.027127s
```
```
$ ruby bench_json_generate.rb
Warming up --------------------------------------
json 78.000 i/100ms
Calculating -------------------------------------
json 789.781 (± 2.7%) i/s - 3.978k in 5.041043s
```
```
require 'json'
require 'benchmark/ips'
obj = []
1000.times do |i|
obj << {
"id" => i,
:age => 42,
}
end
Benchmark.ips do |x|
x.report "json" do |iter|
count = 0
while count < iter
JSON.generate(obj)
count += 1
end
end
end
```
https://github.com/flori/json/commit/38c0f6dbe4
To convert Hash convert, this part was using following pseudo code
```
obj.keys.each do |key|
value = obj[key]
...
end
```
and `rb_funcall()` was called for `obj.keys`.
It might be slightly heavy to call the Ruby method.
This patch will iterate to convert Hash object about key/value using `rb_hash_foreach()` Ruby API instead of `rb_funcall()`.
```
$ ruby bench_json_generate.rb
Warming up --------------------------------------
json 55.000 i/100ms
Calculating -------------------------------------
json 558.501 (± 1.1%) i/s - 2.805k in 5.022986s
```
```
$ ruby bench_json_generate.rb
Warming up --------------------------------------
json 65.000 i/100ms
Calculating -------------------------------------
json 659.576 (± 1.5%) i/s - 3.315k in 5.027127s
```
```
require 'json'
require 'benchmark/ips'
obj = []
1000.times do |i|
obj << {
"id" => i,
:age => 42,
}
end
Benchmark.ips do |x|
x.report "json" do |iter|
count = 0
while count < iter
JSON.generate(obj)
count += 1
end
end
end
```
https://github.com/flori/json/commit/a73323dc5e
`rb_funcall` might be slightly heavy to call the Ruby method.
This patch will convert String encoding using `rb_str_encode()` instead of `rb_funcall()`.
## Before
```
$ ruby bench_json_generate.rb
Warming up --------------------------------------
json 78.000 i/100ms
Calculating -------------------------------------
json 789.781 (± 2.7%) i/s - 3.978k in 5.041043s
```
## After
```
$ ruby bench_json_generate.rb
Warming up --------------------------------------
json 129.000 i/100ms
Calculating -------------------------------------
json 1.300k (± 2.3%) i/s - 6.579k in 5.064656s
```
## Code
```
require 'json'
require 'benchmark/ips'
obj = []
1000.times do |i|
obj << {
"id" => i,
:age => 42,
}
end
Benchmark.ips do |x|
x.report "json" do |iter|
count = 0
while count < iter
JSON.generate(obj)
count += 1
end
end
end
```
https://github.com/flori/json/commit/9ae6d2969c
To get rid of a bug of `onig_region_set` which takes `int`s
instead of `OnigPosition`s, set elements of `beg` and `end`
members directly, for the time being.
Cited from mount(8):
```
strictatime
Always update the file access time when reading from a
file. Without this option the filesystem may default to a
less strict update mode, where some access time updates
are skipped for performance reasons. This option could be
ignored if it is not supported by the filesystem.
```
* ext/openssl/ossl_asn1.c (Init_ossl_asn1): prefer
`rb_gc_register_mark_object`, which is better for constant
objects, over `rb_gc_register_address` for global/static
variables which can be re-assigned at runtime. [Bug #16196]
* ext/openssl/ossl_asn1.c (Init_ossl_asn1): register the static
variable to grab an internal object, before creating the object.
otherwise the just-created object could get collected during the
global variable list allocation. [Bug #16196]
There have been some direct changes in parser.c which is automatically
generated from parser.rl. This updates parser.rl to sync the changes:
* 91793b8967
* 79ead821dd
* 80b5a0ff2a
This reverts commits: 10d6a3aca78ba48c1b85fba8627dc1dd883de5ba6c6a25feca167e6b48f17cb96d41a53207979278595b3c4fdd1521f7cf89c11c5e69accf336082033632a812c0f56506be0d86427a3219 .
The reason for the revert is that we observe ABA problem around
inline method cache. When a cache misshits, we search for a
method entry. And if the entry is identical to what was cached
before, we reuse the cache. But the commits we are reverting here
introduced situations where a method entry is freed, then the
identical memory region is used for another method entry. An
inline method cache cannot detect that ABA.
Here is a code that reproduce such situation:
```ruby
require 'prime'
class << Integer
alias org_sqrt sqrt
def sqrt(n)
raise
end
GC.stress = true
Prime.each(7*37){} rescue nil # <- Here we populate CC
class << Object.new; end
# These adjacent remove-then-alias maneuver
# frees a method entry, then immediately
# reuses it for another.
remove_method :sqrt
alias sqrt org_sqrt
end
Prime.each(7*37).to_a # <- SEGV
```
Currently, there is not a way to create a sized enumerator in C
with a different set of arguments than provided by Ruby, and
correctly handle keyword arguments. This function allows that.
The need for this is fairly uncommon, but it occurs at least in
Enumerator.produce, which takes arugments from Ruby but calls
rb_enumeratorize_with_size with a different set of arguments.
This adds rb_funcall_passing_block_kw, rb_funcallv_public_kw,
and rb_yield_splat_kw. This functions are necessary to easily
handle cases where rb_funcall_passing_block, rb_funcallv_public,
and rb_yield_splat are currently used and a keyword argument
separation warning is raised.
Now that we have eliminated most destructive operations over the
rb_method_entry_t / rb_callable_method_entry_t, let's make them
mostly immutabe and mark them const.
One exception is rb_export_method(), which destructively modifies
visibilities of method entries. I have left that operation as is
because I suspect that destructiveness is the nature of that
function.