aboutsummaryrefslogtreecommitdiffstats
path: root/hash.c
Commit message (Collapse)AuthorAgeFilesLines
* [ci skip] Doc-only enhancements for HashBurdette Lamar2020-03-271-11/+112
| | | About the defalut values.
* Reduce allocations for keyword argument hashesJeremy Evans2020-03-171-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, passing a keyword splat to a method always allocated a hash on the caller side, and accepting arbitrary keywords in a method allocated a separate hash on the callee side. Passing explicit keywords to a method that accepted a keyword splat did not allocate a hash on the caller side, but resulted in two hashes allocated on the callee side. This commit makes passing a single keyword splat to a method not allocate a hash on the caller side. Passing multiple keyword splats or a mix of explicit keywords and a keyword splat still generates a hash on the caller side. On the callee side, if arbitrary keywords are not accepted, it does not allocate a hash. If arbitrary keywords are accepted, it will allocate a hash, but this commit uses a callinfo flag to indicate whether the caller already allocated a hash, and if so, the callee can use the passed hash without duplicating it. So this commit should make it so that a maximum of a single hash is allocated during method calls. To set the callinfo flag appropriately, method call argument compilation checks if only a single keyword splat is given. If only one keyword splat is given, the VM_CALL_KW_SPLAT_MUT callinfo flag is not set, since in that case the keyword splat is passed directly and not mutable. If more than one splat is used, a new hash needs to be generated on the caller side, and in that case the callinfo flag is set, indicating the keyword splat is mutable by the callee. In compile_hash, used for both hash and keyword argument compilation, if compiling keyword arguments and only a single keyword splat is used, pass the argument directly. On the caller side, in vm_args.c, the callinfo flag needs to be recognized and handled. Because the keyword splat argument may not be a hash, it needs to be converted to a hash first if not. Then, unless the callinfo flag is set, the hash needs to be duplicated. The temporary copy of the callinfo flag, kw_flag, is updated if a hash was duplicated, to prevent the need to duplicate it again. If we are converting to a hash or duplicating a hash, we need to update the argument array, which can including duplicating the positional splat array if one was passed. CALLER_SETUP_ARG and a couple other places needs to be modified to handle similar issues for other types of calls. This includes fairly comprehensive tests for different ways keywords are handled internally, checking that you get equal results but that keyword splats on the caller side result in distinct objects for keyword rest parameters. Included are benchmarks for keyword argument calls. Brief results when compiled without optimization: def kw(a: 1) a end def kws(**kw) kw end h = {a: 1} kw(a: 1) # about same kw(**h) # 2.37x faster kws(a: 1) # 1.30x faster kws(**h) # 2.19x faster kw(a: 1, **h) # 1.03x slower kw(**h, **h) # about same kws(a: 1, **h) # 1.16x faster kws(**h, **h) # 1.14x faster
* hash.c: Do not use the fast path (rb_yield_values) for lambda blocksYusuke Endoh2020-03-161-3/+3
| | | | | | | | | | | | | | | | | As a semantics, Hash#each yields a 2-element array (pairs of keys and values). So, `{ a: 1 }.each(&->(k, v) { })` should raise an exception due to lambda's arity check. However, the optimization that avoids Array allocation by using rb_yield_values for blocks whose arity is more than 1 (introduced at b9d29603375d17c3d1d609d9662f50beaec61fa1 and some commits), seemed to overlook the lambda case, and wrongly allowed the code above to work. This change experimentally attempts to make it strict; now the code above raises an ArgumentError. This is an incompatible change; if the compatibility issue is bigger than our expectation, it may be reverted (until Ruby 3.0 release). [Bug #12706]
* Add missing write barrier for Hash#transform_values{,!}Alan Wu2020-03-151-3/+4
| | | | | | | 21994b7fd686f263544fcac1616ecf3189fb78b3 removed the write barrier that was present in rb_hash_aset(). Re-insert it to not crash during GC. [Bug #16689]
* Cast properly for shift operandKoichi Sasada2020-03-091-1/+1
| | | | `(int) << RHASH_LEV_SHIFT` can be negative integer.
* check ar_table first.Koichi Sasada2020-03-071-2/+5
| | | | | RHASH_AR_TABLE_SIZE() has assertion that it is a ar_talbe. The last commit breaks this assumption so check ar_table first.
* check ar_table after `#hash` callKoichi Sasada2020-03-071-0/+18
| | | | | | | ar_table can be converted to st_table just after `ar_do_hash()` function which calls `#hash` method. We need to check the representation to detect this mutation. [Bug #16676]
* fix compile error w/ -DUSE_TRANSIENT_HEAP=0卜部昌平2020-03-041-0/+2
| | | | | rb_transient_heap_managed_ptr_p is available only when USE_TRANSIENT_HEAP. Need #if guards.
* hash.c: [DOC] fix examples for ENV.merge!Marcus Stollsteimer2020-02-221-5/+6
|
* More ENV rdoc [ci skip]Burdette Lamar2020-02-221-61/+116
|
* [DOC] Fixed `ENV.rassoc` result order [ci skip]Nobuyoshi Nakada2020-02-201-2/+3
|
* hash.c: [DOC] fix typosMarcus Stollsteimer2020-02-191-3/+3
|
* [DOC] use local variable like names [ci skip]Nobuyoshi Nakada2020-02-151-24/+24
| | | | | Use local variable like name as return value which is an instance of that class but not constant itself.
* Fix typos and add a space [ci skip]Kazuhiro NISHIYAMA2020-02-141-3/+3
|
* Enhanced doc for ENVBurdette Lamar2020-02-141-28/+61
| | | * More on ENV examples
* Enhance rdoc for ENVBurdette Lamar2020-02-091-14/+80
|
* Extract a function, ruby_reset_timezone().Tanaka Akira2020-01-281-3/+3
| | | | | Initial implementation of ruby_reset_timezone() assigns ruby_tz_uptodate_p to false.
* Added rb_warn_deprecated_to_removeNobuyoshi Nakada2020-01-231-1/+1
| | | | | Warn the deprecation and future removal, with obeying the warning flag.
* Make taint warnings non-verbose instead of verboseJeremy Evans2020-01-221-1/+1
|
* hash.c: Add a feature to manipulate ruby2_keywords flagYusuke Endoh2020-01-171-0/+49
| | | | | | | | | | | | | | | It was found that a feature to check and add ruby2_keywords flag to an existing Hash is needed when arguments are serialized and deserialized. It is possible to do the same without explicit APIs, but it would be good to provide them as a core feature. https://github.com/rails/rails/pull/38105#discussion_r361863767 Hash.ruby2_keywords_hash?(hash) checks if hash is flagged or not. Hash.ruby2_keywords_hash(hash) returns a duplicated hash that has a ruby2_keywords flag, [Bug #16486]
* reload AR table body for transient heap.Koichi Sasada2020-01-131-0/+1
| | | | | | ar_talbe (Hash representation for <=8 size) can use transient heap and the memory area can move. So we need to restore `pair' ptr after `func` call (which can run any programs) because of moving.
* Reduced duplicate codeNobuyoshi Nakada2020-01-101-6/+1
|
* Hash#transform_values should return a plain new HashNobuyoshi Nakada2020-01-101-4/+9
| | | | [Bug #16498]
* Hoisted out call_default_procNobuyoshi Nakada2020-01-081-8/+10
|
* Adjusted indents [ci skip]Nobuyoshi Nakada2020-01-081-4/+4
|
* Speeds up fallback to Hash#default_proc in rb_hash_aref by removing a method ↵Lourens Naudé2020-01-081-5/+7
| | | | call
* move internal/debug.h definitions to internal.hKoichi Sasada2020-01-031-1/+0
| | | | Debug utilities should be accessible from any internal code.
* `#include "internal/debug"` seems to be needed in assert modeYusuke Endoh2019-12-261-0/+1
| | | | http://ci.rvm.jp/results/trunk-theap-asserts@silicon-docker/2525210
* decouple internal.h headers卜部昌平2019-12-261-10/+23
| | | | | | | | | | | | | | | | | | Saves comitters' daily life by avoid #include-ing everything from internal.h to make each file do so instead. This would significantly speed up incremental builds. We take the following inclusion order in this changeset: 1. "ruby/config.h", where _GNU_SOURCE is defined (must be the very first thing among everything). 2. RUBY_EXTCONF_H if any. 3. Standard C headers, sorted alphabetically. 4. Other system headers, maybe guarded by #ifdef 5. Everything else, sorted alphabetically. Exceptions are those win32-related headers, which tend not be self- containing (headers have inclusion order dependencies).
* internal/hash.h rework卜部昌平2019-12-261-2/+2
| | | | | | | | Reduce macros to make them inline functions, as well as mark MJIT_FUNC_EXPORTED functions explicitly as such. Definition of ar_hint_t is simplified. This has been the only possible definition so far.
* Transform hash keys by a hash [Feature #16274]Nobuyoshi Nakada2019-12-261-9/+68
|
* Enhancements for ENV docBurdetteLamar2019-12-221-13/+55
|
* Added rb_warn_deprecatedNobuyoshi Nakada2019-12-191-2/+2
|
* Enhancements for ENV docBurdetteLamar2019-12-161-46/+194
|
* Avoid unnecessary tzset() callKOSAKI Motohiro2019-12-011-3/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Akatsuki reported ENV['TZ'] = 'UTC' improved 7x-8x faster on following code. t = Time.now; 100000.times { Time.new(2019) }; Time.now - t https://hackerslab.aktsk.jp/2019/12/01/141551 commit 4bc1669127(reduce tzset) dramatically improved this situation. But still, TZ=UTC is faster than default. This patch removs unnecessary tzset() call completely. Performance check ---------------------- test program: t = Time.now; 100000.times { Time.new(2019) }; Time.now - t before: 0.387sec before(w/ TZ): 0.197sec after: 0.162sec after(w/ TZ): 0.165sec OK. Now, Time creation 2x faster *and* TZ=UTC doesn't improve anything. We can forget this hack completely. :) Side note: This patch slightly changes Time.new(t) behavior implicitly. Before this patch, it might changes default timezone implicitly. But after this patch, it doesn't. You need to reset TZ (I mean ENV['TZ'] = nil) explicitly. But I don't think this is big impact. Don't try to change /etc/localtime on runtime. Side note2: following test might be useful for testing "ENV['TZ'] = nil". ----------------------------------------- % cat <<'End' | sudo sh -s rm -f /etc/localtime-; cp -a /etc/localtime /etc/localtime- rm /etc/localtime; ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime ./ruby -e ' p Time.new(2000).zone # JST File.unlink("/etc/localtime"); File.symlink("/usr/share/zoneinfo/America/Los_Angeles", "/etc/localtime") p Time.new(2000).zone # JST (ruby does not follow /etc/localtime modification automatically) ENV["TZ"] = nil p Time.new(2000).zone # PST (ruby detect /etc/localtime modification) ' rm /etc/localtime; cp -a /etc/localtime- /etc/localtime; rm /etc/localtime- End
* ENV.update should not call block on existing keysNobuyoshi Nakada2019-11-301-3/+13
| | | | [Bug #16192]
* Improve consistency of bool/true/falseKazuhiro NISHIYAMA2019-11-251-1/+1
|
* make functions static卜部昌平2019-11-191-3/+5
| | | | | | | These functions are used from within a compilation unit so we can make them static, for better binary size. This changeset reduces the size of generated ruby binary from 26,590,128 bytes to 26,584,472 bytes on my macihne.
* Deprecate taint/trust and related methods, and make the methods no-opsJeremy Evans2019-11-181-46/+7
| | | | | | This removes the related tests, and puts the related specs behind version guards. This affects all code in lib, including some libraries that may want to support older versions of Ruby.
* Warn on access/modify of $SAFE, and remove effects of modifying $SAFEJeremy Evans2019-11-181-2/+0
| | | | | | | | | | | | | | | | | This removes the security features added by $SAFE = 1, and warns for access or modification of $SAFE from Ruby-level, as well as warning when calling all public C functions related to $SAFE. This modifies some internal functions that took a safe level argument to no longer take the argument. rb_require_safe now warns, rb_require_string has been added as a version that takes a VALUE and does not warn. One public C function that still takes a safe level argument and that this doesn't warn for is rb_eval_cmd. We may want to consider adding an alternative method that does not take a safe level argument, and warn for rb_eval_cmd.
* delete unused functions卜部昌平2019-11-141-2/+2
| | | | | | | | | | | | Looking at the list of symbols inside of libruby-static.a, I found hundreds of functions that are defined, but used from nowhere. There can be reasons for each of them (e.g. some functions are specific to some platform, some are useful when debugging, etc). However it seems the functions deleted here exist for no reason. This changeset reduces the size of ruby binary from 26,671,456 bytes to 26,592,864 bytes on my machine.
* Use a monotonically increasing number for object_idJohn Hawthorn2019-11-071-2/+6
| | | | | | | | | | | | | | | | | This changes object_id from being based on the objects location in memory (or a nearby memory location in the case of a conflict) to be based on an always increasing number. This number is a Ruby Integer which allows it to overflow the size of a pointer without issue (very unlikely to happen in real programs especially on 64-bit, but a nice guarantee). This changes obj_to_id_tbl and id_to_obj_tbl to both be maps of Ruby objects to Ruby objects (previously they were Ruby object to C integer) which simplifies updating them after compaction as we can run them through gc_update_table_refs. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Revert "Use a monotonically increasing number for object_id"Aaron Patterson2019-11-061-6/+2
| | | | This reverts commit bd2b314a05ae9192b3143e1e678a37c370d8a9ce.
* Use a monotonically increasing number for object_idJohn Hawthorn2019-11-061-2/+6
| | | | | | | | | | | | | | | | | This changes object_id from being based on the objects location in memory (or a nearby memory location in the case of a conflict) to be based on an always increasing number. This number is a Ruby Integer which allows it to overflow the size of a pointer without issue (very unlikely to happen in real programs especially on 64-bit, but a nice guarantee). This changes obj_to_id_tbl and id_to_obj_tbl to both be maps of Ruby objects to Ruby objects (previously they were Ruby object to C integer) which simplifies updating them after compaction as we can run them through gc_update_table_refs. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Put an empty line [ci skip]Nobuyoshi Nakada2019-11-051-1/+2
|
* More rdoc for ENVBurdette Lamar2019-11-051-0/+28
|
* Correct documented return values for certain ENV methods (#2620)Burdette Lamar2019-11-021-8/+8
|
* hash.c: Do not use Unicode double-quotesYusuke Endoh2019-10-241-1/+1
| | | | | | | | | | | | | | | | It made rdoc fail. https://rubyci.org/logs/rubyci.s3.amazonaws.com/ubuntu1804/ruby-master/log/20191023T183005Z.fail.html.gz ``` RDoc is not a full Ruby parser and will fail when fed invalid ruby programs. The internal error was: (ArgumentError) invalid byte sequence in US-ASCII uh-oh! RDoc had a problem: invalid byte sequence in US-ASCII ```
* More rdoc for ENV#[] and ENV#fetchBurdetteLamar2019-10-231-13/+30
|
* [Bug #16121] adjusted indent [ci skip]Nobuyoshi Nakada2019-10-211-15/+15
|