The documentation states it returns a copy of self with nil value
entries removed. However, the previous behavior was creating a
plain new hash with non-nil values copied into it. This change
aligns the behavior with the documentation.
Fixes [Bug #19113]
This was already copied for non-empty hashes. As Hash.ruby2_keywords_hash
copies default values, it should also copy the compare_by_identity flag.
Partially Fixes [Bug #19113]
It wasn't copied for empty hashes, and Hash.[] doesn't copy the
default value, so copying the compare_by_identity flag does not
make sense.
Partially Fixes [Bug #19113]
Because of the function pointer, it's hard to figure out what hash
functions could be used in Hash objects when st_lookup is used.
Having this assertion makes it easier to understand what
hash_stlike_lookup could possibly do. (AR uses only rb_any_hash)
For example, this clarifies that hash_stlike_lookup never calls a #hash
method when a key is T_STRING or T_SYMBOL.
We should always have a T_HASH here, so we can use FL_TEST_RAW to avoid
checking whether we may have an immediate value.
I expect this to be a very small performance improvement (perf stat
./miniruby benchmark/hash_aref_miss.rb shows a ~1% improvement). It also
removes 9 instructions from rb_hash_default_value on x86_64.
On a hash miss we need to call default if it is redefined in order to
return the default value to be used. Previously we checked this with
rb_method_basic_definition_p, which avoids the method call but requires
a method lookup.
This commit replaces the previous check with BASIC_OP_UNREDEFINED_P and
a new BOP_DEFAULT. We still need to fall back to
rb_method_basic_definition_p when called on a subclasss of hash.
| |compare-ruby|built-ruby|
|:---------------|-----------:|---------:|
|hash_aref_miss | 2.692| 3.531|
| | -| 1.31x|
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
Co-authored-by: "Ian C. Anderson" <ian@iancanderson.com>
Co-authored-by: Jack McCracken <me@jackmc.xyz>
One year ago, the former method has been deprecated while the latter
has become an error. Then the 3.1 released, it is enough time to make
also the former an error.
rb_ary_tmp_new suggests that the array is temporary in some way, but
that's not true, it just creates an array that's hidden and not on the
transient heap. This commit renames it to rb_ary_hidden_new.
Previously, because opt_aref and opt_aset don't push a frame, when they
would call rb_hash to determine the hash value of the key, the initial
level of recursion would incorrectly use the method id at the top of the
stack instead of "hash".
This commit replaces rb_exec_recursive_outer with
rb_exec_recursive_outer_mid, which takes an explicit method id, so that
we can make the hash calculation behave consistently.
rb_exec_recursive_outer was documented as being internal, so I believe
this should be okay to change.
[Feature #18683]
This allows parsers and similar libraries to create Hashes of
a certain capacity in advance. It's useful when the key and values
are streamed, hence `bulk_insert()` can't be used.
Method references is not only able to be marked up as code, also
reflects `--show-hash` option.
The bug that prevented the old rdoc from correctly parsing these
methods was fixed last month.
I used this regex:
([A-Za-z]+)\.html#(?:class|module)-[A-Za-z]+-label-([A-Za-z0-9\-\+]+)
And performed a global find & replace for this:
rdoc-ref:$1@$2
Before this change the write barrier was executed before the key and
value were actually reachable via the Hash. This could cause
inconsistencies in object coloration which would lead to accidental
collection of dup'd keys.
Example:
1. Object O is grey, Object P is white.
2. Write barrier fires O -> P
3. Write barrier does nothing
4. Malloc happens, which starts GC
5. GC colors O black
6. P is written in to O (now we have O -> P reference)
7. P is now accidentally treated as garbage
We found that we need to make Ruby objects while locking the environ
to ENV operation atomically, so we decided to use `RB_VM_LOCK_ENTER()`
instead of `env_lock`.