summaryrefslogtreecommitdiff
path: root/compile.c
AgeCommit message (Collapse)Author
2019-08-04merge revision(s) 66977: [Backport #15578]nagachika
Revert r63383, r63248 "compile.c: copy a short insn with leave" When copying `leave` insn, TRACE also should be copied if it is present, but this optimization is trivial and not worth the complexity. [ruby-core:91366] [Bug #15578] 4cae5353c03009beb1e0a1619422072773580609 5afd479de63b6609ddcd1510da94d2c1ac384f7f git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67726 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-07-28merge revision(s) a6a26e42b15c46f117f4fce07a2050e9d727355d: [Backport #15906]nagachika
compile.c: Partially revert r63870 which caused wrong optimization [Bug #15906] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67716 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-14merge revision(s) 66670,66676: [Backport #15476]naruse
compile.c: support branch coverage for `a&.foo = 1` [Bug #15476] compile.c (iseq_set_sequence): fix branch coverage table Not only TRACE_ELEMENT but also INSN_ELEMENT may have events. The old pc2branchindex was created using only events of TRACE_ELEMENTs. This change uses events of INSN_ELEMENTs too for pc2branchindex table. [Bug #15476] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@66813 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-20hide iseq operand object for duphash. [Bug #15440]ko1
* compile.c (compile_array): hide source Hash object. * hash.c (rb_hash_resurrect): introduced to dup Hash object using rb_cHash. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-20Freeze hash literals embedded in duphash instructionsnobu
Previously, these hash literals were not frozen, and thus could be modified by ObjectSpace, resulting in undesired behavior. Example: ```ruby require 'objspace' def a(b={0=>1,1=>4,2=>17}) b end p a ObjectSpace.each_object(Hash) do |a| a[3] = 8 if a.class == Hash && a[0] == 1 && a[1] == 4 && a[2] == 17 end p a ``` It may be desirable to hide such hashes from ObjectSpace, since they are internal, but I'm not sure how to do that. From: Jeremy Evans <code@jeremyevans.net> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66464 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-13Don't increment `code_index`tenderlove
`code_index` doesn't need to be incremented since the mark array has been removed. Thanks for the patch ko1! [ruby-core:90456] [Bug #15406] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66376 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-12param.flags.has_kw flag should be FALSE before setting param.keyword.ko1
* compile.c (ibf_load_iseq_each): iseq_mark assumes that if param.flags.has_kw is TRUE, then param.keyword is not NULL. To confirm this assumption, make it FALSE before param.keyword is initialized. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66367 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-12restore `catch_except_p` flag.ko1
* compile.c: we need to restore `catch_except_p` flag at `load_from_binary`. [Bug #15395] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66366 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-11Fix infinite loop by ensurenobu
* compile.c (iseq_insert_nop_between_end_and_cont): insert nop so that the end of rescue and continuing points are not same, to get rid of infinite loop. [Bug #15385] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66326 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-11* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66325 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-11Modify insn list only when compilingnobu
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66324 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-09raise instead of rb_bugnobu
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66293 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-06* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66259 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-06Speed up hash literals by dupingtenderlove
This commit replaces the `newhashfromarray` instruction with a `duphash` instruction. Instead of allocating a new hash from an array stored in the Instruction Sequences, store a hash directly in the instruction sequences and dup it on execution. == Instruction sequence changes == ```ruby code = <<-eorby { "foo" => "bar", "baz" => "lol" } eorby insns = RubyVM::InstructionSequence.compile(code, __FILE__, nil, 0, frozen_string_literal: true) puts insns.disasm ``` On Ruby 2.5: ``` == disasm: #<ISeq:<compiled>@test.rb:0 (0,0)-(0,36)>==================== 0000 putobject "foo" 0002 putobject "bar" 0004 putobject "baz" 0006 putobject "lol" 0008 newhash 4 0010 leave ``` Ruby 2.6@r66174 3b6321083a2e3525da3b34d08a0b68bac094bd7f: ``` $ ./ruby test.rb == disasm: #<ISeq:<compiled>@test.rb:0 (0,0)-(0,36)> (catch: FALSE) 0000 newhashfromarray 2, ["foo", "bar", "baz", "lol"] 0003 leave ``` Ruby 2.6 + This commit: ``` $ ./ruby test.rb == disasm: #<ISeq:<compiled>@test.rb:0 (0,0)-(0,36)> (catch: FALSE) 0000 duphash {"foo"=>"bar", "baz"=>"lol"} 0002 leave ``` == Benchmark Results == Compared to 2.5.3: ``` $ make benchmark ITEM=hash_literal_small COMPARE_RUBY=/Users/aaron/.rbenv/versions/2.5.3/bin/ruby generating known_errors.inc known_errors.inc unchanged ./revision.h unchanged /Users/aaron/.rbenv/shims/ruby --disable=gems -rrubygems -I./benchmark/lib ./benchmark/benchmark-driver/exe/benchmark-driver \ --executables="compare-ruby::/Users/aaron/.rbenv/versions/2.5.3/bin/ruby -I.ext/common --disable-gem" \ --executables="built-ruby::./miniruby -I./lib -I. -I.ext/common -r./prelude --disable-gem" \ $(find ./benchmark -maxdepth 1 -name '*hash_literal_small*.yml' -o -name '*hash_literal_small*.rb' | sort) Calculating ------------------------------------- compare-ruby built-ruby hash_literal_small2 1.498 1.877 i/s - 1.000 times in 0.667581s 0.532656s hash_literal_small4 1.197 1.642 i/s - 1.000 times in 0.835375s 0.609160s hash_literal_small8 0.620 1.215 i/s - 1.000 times in 1.611638s 0.823090s Comparison: hash_literal_small2 built-ruby: 1.9 i/s compare-ruby: 1.5 i/s - 1.25x slower hash_literal_small4 built-ruby: 1.6 i/s compare-ruby: 1.2 i/s - 1.37x slower hash_literal_small8 built-ruby: 1.2 i/s compare-ruby: 0.6 i/s - 1.96x slower ``` Compared to r66255 ``` $ make benchmark ITEM=hash_literal_small COMPARE_RUBY=/Users/aaron/.rbenv/versions/ruby-trunk/bin/ruby generating known_errors.inc known_errors.inc unchanged ./revision.h unchanged /Users/aaron/.rbenv/shims/ruby --disable=gems -rrubygems -I./benchmark/lib ./benchmark/benchmark-driver/exe/benchmark-driver \ --executables="compare-ruby::/Users/aaron/.rbenv/versions/ruby-trunk/bin/ruby -I.ext/common --disable-gem" \ --executables="built-ruby::./miniruby -I./lib -I. -I.ext/common -r./prelude --disable-gem" \ $(find ./benchmark -maxdepth 1 -name '*hash_literal_small*.yml' -o -name '*hash_literal_small*.rb' | sort) Calculating ------------------------------------- compare-ruby built-ruby hash_literal_small2 1.567 1.831 i/s - 1.000 times in 0.638056s 0.546039s hash_literal_small4 1.298 1.652 i/s - 1.000 times in 0.770214s 0.605182s hash_literal_small8 0.873 1.216 i/s - 1.000 times in 1.145304s 0.822047s Comparison: hash_literal_small2 built-ruby: 1.8 i/s compare-ruby: 1.6 i/s - 1.17x slower hash_literal_small4 built-ruby: 1.7 i/s compare-ruby: 1.3 i/s - 1.27x slower hash_literal_small8 built-ruby: 1.2 i/s compare-ruby: 0.9 i/s - 1.39x slower ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66258 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-03* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66175 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-03Collapse putobject, putobject, newarraytenderlove
This collapses: ``` == disasm: #<ISeq:bar@bench.rb:3 (3,0)-(5,3)> (catch: FALSE) 0000 putobject "a" ( 4)[LiCa] 0002 putobject "b" 0004 putobject "c" 0006 putobject "d" 0008 putobject "e" 0010 putobject "f" 0012 putobject "g" 0014 putobject "h" 0016 putobject "i" 0018 putobject "j" 0020 putobject "k" 0022 newarray 11 0024 leave ( 5)[Re] ``` In to this: ``` == disasm: #<ISeq:bar@bench.rb:3 (3,0)-(5,3)> (catch: FALSE) 0000 duparray ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]( 4)[LiCa] 0002 leave ( 5)[Re] ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66174 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-01Revert "Collapse putobject, putobject, newarray"tenderlove
This reverts commit cbdf5a1842cda89347a2c840d23c35f041aead68. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66109 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-30* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66107 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-30Collapse putobject, putobject, newarraytenderlove
This collapses: ``` == disasm: #<ISeq:bar@bench.rb:3 (3,0)-(5,3)> (catch: FALSE) 0000 putobject "a" ( 4)[LiCa] 0002 putobject "b" 0004 putobject "c" 0006 putobject "d" 0008 putobject "e" 0010 putobject "f" 0012 putobject "g" 0014 putobject "h" 0016 putobject "i" 0018 putobject "j" 0020 putobject "k" 0022 newarray 11 0024 leave ( 5)[Re] ``` In to this: ``` == disasm: #<ISeq:bar@bench.rb:3 (3,0)-(5,3)> (catch: FALSE) 0000 duparray ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]( 4)[LiCa] 0002 leave ( 5)[Re] ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66106 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-27* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66026 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-27compile.c: prevent out-of-bound initialization of coverage countersmame
The coverage counters is initialized with `counter[lineno - 1] = 0`, but lineno may be 0, which led to write access for index -1. [ruby-core:90085] [Bug#15346] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66025 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-10Fix potential NULL pointer access [ci skip]nobu
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65650 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-08compile.c: compile error than rb_bug [ci skip]nobu
* compile.c (get_local_var_idx, get_dyna_var_idx): raise a compile error which is useful than rb_bug, when ID is not found. * compile.c (iseq_set_sequence): ditto when IC index overflow, with dumping generated code. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65617 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-08compile.c: unreachable than rb_bug [ci skip]nobu
* compile.c (iseq_calc_param_size): use UNREACHABLE than rb_bug, at where never reachable. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65614 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-07* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65601 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-07Rename get/setinlinecache to opt_get/opt_setinlinecachemame
The instructions are just for optimization. To clarity the intention, this change adds the prefix "opt_", like "opt_case_dispatch". git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65600 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-06Fix TracePoint for nested iseq loaded from binary [Bug#14702]ko1
When loading iseq from binary while a TracePoint is on, we need to recompile instructions to their "trace_" variant. Before this commit we only recompiled instructions in the top level iseq, which meant that TracePoint was malfunctioning for code inside module/class/method definitions. * compile.c: Move rb_iseq_init_trace to rb_ibf_load_iseq_complete. It is called on all iseqs during loading. * test_iseq.rb: Test that tracepoints fire within children iseq when using load_from_binary. This patch is from: Alan Wu <XrXr@users.noreply.github.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65567 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-05Implement `RubyVM::AST.of` [Feature #14836]yui-knk
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65542 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30* remove trailing spaces, expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65455 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30support theap for T_HASH. [Feature #14989]ko1
* hash.c, internal.h: support theap for small Hash. Introduce RHASH_ARRAY (li_table) besides st_table and small Hash (<=8 entries) are managed by an array data structure. This array data can be managed by theap. If st_table is needed, then converting array data to st_table data. For st_table using code, we prepare "stlike" APIs which accepts hash value and are very similar to st_ APIs. This work is based on the GSoC achievement by tacinight <tacingiht@gmail.com> and refined by ko1. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65454 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65450 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30introduce TransientHeap. [Bug #14858]ko1
* transient_heap.c, transient_heap.h: implement TransientHeap (theap). theap is designed for Ruby's object system. theap is like Eden heap on generational GC terminology. theap allocation is very fast because it only needs to bump up pointer and deallocation is also fast because we don't do anything. However we need to evacuate (Copy GC terminology) if theap memory is long-lived. Evacuation logic is needed for each type. See [Bug #14858] for details. * array.c: Now, theap for T_ARRAY is supported. ary_heap_alloc() tries to allocate memory area from theap. If this trial sccesses, this array has theap ptr and RARRAY_TRANSIENT_FLAG is turned on. We don't need to free theap ptr. * ruby.h: RARRAY_CONST_PTR() returns malloc'ed memory area. It menas that if ary is allocated at theap, force evacuation to malloc'ed memory. It makes programs slow, but very compatible with current code because theap memory can be evacuated (theap memory will be recycled). If you want to get transient heap ptr, use RARRAY_CONST_PTR_TRANSIENT() instead of RARRAY_CONST_PTR(). If you can't understand when evacuation will occur, use RARRAY_CONST_PTR(). (re-commit of r65444) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65449 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65448 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30revert r65444 and r65446 because of commit missko1
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65447 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65445 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30introduce TransientHeap. [Bug #14858]ko1
* transient_heap.c, transient_heap.h: implement TransientHeap (theap). theap is designed for Ruby's object system. theap is like Eden heap on generational GC terminology. theap allocation is very fast because it only needs to bump up pointer and deallocation is also fast because we don't do anything. However we need to evacuate (Copy GC terminology) if theap memory is long-lived. Evacuation logic is needed for each type. See [Bug #14858] for details. * array.c: Now, theap for T_ARRAY is supported. ary_heap_alloc() tries to allocate memory area from theap. If this trial sccesses, this array has theap ptr and RARRAY_TRANSIENT_FLAG is turned on. We don't need to free theap ptr. * ruby.h: RARRAY_CONST_PTR() returns malloc'ed memory area. It menas that if ary is allocated at theap, force evacuation to malloc'ed memory. It makes programs slow, but very compatible with current code because theap memory can be evacuated (theap memory will be recycled). If you want to get transient heap ptr, use RARRAY_CONST_PTR_TRANSIENT() instead of RARRAY_CONST_PTR(). If you can't understand when evacuation will occur, use RARRAY_CONST_PTR(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65444 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65439 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30use RARRAY_AREF() instead of RARRAY_CONST_PTR().ko1
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65438 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-29compile.c: fix up r65411kazu
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65429 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-28use a rb_ function instead of st_ directly.ko1
* compile.c (ibf_dump_object_hash): use `rb_hash_foreach()` instead of using `st_foreach()`. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65411 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-24compile.c: fix peephole optimizationnobu
* compile.c (iseq_peephole_optimize): should `pop` before jump instruction which succeeds to `newarray` of a literal object, not after. [ruby-core:89536] [Bug #15245] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65350 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-24introduce new YARV insn newhashfromarray.ko1
* insns.def (newhashfromarray): added to replace `core_hash_from_ary` method to eliminate method call overhead. On my environment, I got the following benchmark results: x = {x: 1} modified: 7864988.6 i/s trunk: 6004098.1 i/s - 1.31x slower x = {x: 1, y: 2} trunk: 6127338.4 i/s modified: 5232380.0 i/s - 1.17x slower x = {x: 1, y: 2, z: 3} modified: 6089553.1 i/s trunk: 5249333.5 i/s - 1.16x slower This trivial improvement should be reconsider because of usage of this instruction. * compile.c: ditto. * defs/id.def, vm.c: remove unused functions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65343 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-20* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65226 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-20Remove tracecoverage instructionsmame
The instructions were used only for branch coverage. Instead, it now uses a trace framework [Feature #14104]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65225 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-20ext/coverage/: add the oneshot modemame
This patch introduces "oneshot_lines" mode for `Coverage.start`, which checks "whether each line was executed at least once or not", instead of "how many times each line was executed". A hook for each line is fired at most once, and after it is fired, the hook flag was removed; it runs with zero overhead. See [Feature #15022] in detail. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65195 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-19compile.c: default_len is positiveshyouhei
Recent GCC warns that default_len can be negative (thus can overflow PTRDIFF_MAX), which is a false assert. Suppresses warnings by adding __builtin_unreachable. See also: https://travis-ci.org/ruby/ruby/jobs/443568193#L2227 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65167 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-17* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65108 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-17Remove the level information from throw instructionmame
It is no longer used. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65107 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-13Prefer `rb_fstring_lit` over `rb_fstring_cstr`nobu
The former states explicitly that the argument must be a literal, and can optimize away `strlen` on all compilers. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65059 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-26* expand tabs.svn
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64851 b2dd03c8-39d4-4d8f-98ff-823fe69b080e