summaryrefslogtreecommitdiff
path: root/insns.def
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2022-06-06 17:27:56 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2023-04-18 17:16:22 -0700
commitc5fc1ce975ecdf1c6818714e47579c5d3531c4ca (patch)
tree77a0f348d00a99281f826dac90e1d288c3139051 /insns.def
parent3016f30c956413268655dcb25dbe5041684f9528 (diff)
Emit special instruction for array literal + .(hash|min|max)
This commit introduces a new instruction `opt_newarray_send` which is used when there is an array literal followed by either the `hash`, `min`, or `max` method. ``` [a, b, c].hash ``` Will emit an `opt_newarray_send` instruction. This instruction falls back to a method call if the "interested" method has been monkey patched. Here are some examples of the instructions generated: ``` $ ./miniruby --dump=insns -e '[@a, @b].max' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE) 0000 getinstancevariable :@a, <is:0> ( 1)[Li] 0003 getinstancevariable :@b, <is:1> 0006 opt_newarray_send 2, :max 0009 leave $ ./miniruby --dump=insns -e '[@a, @b].min' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE) 0000 getinstancevariable :@a, <is:0> ( 1)[Li] 0003 getinstancevariable :@b, <is:1> 0006 opt_newarray_send 2, :min 0009 leave $ ./miniruby --dump=insns -e '[@a, @b].hash' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,13)> (catch: FALSE) 0000 getinstancevariable :@a, <is:0> ( 1)[Li] 0003 getinstancevariable :@b, <is:1> 0006 opt_newarray_send 2, :hash 0009 leave ``` [Feature #18897] [ruby-core:109147] Co-authored-by: John Hawthorn <jhawthorn@github.com>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6090
Diffstat (limited to 'insns.def')
-rw-r--r--insns.def33
1 files changed, 17 insertions, 16 deletions
diff --git a/insns.def b/insns.def
index ba16d6365c..a457372112 100644
--- a/insns.def
+++ b/insns.def
@@ -899,8 +899,8 @@ opt_str_uminus
}
DEFINE_INSN
-opt_newarray_max
-(rb_num_t num)
+opt_newarray_send
+(rb_num_t num, ID method)
(...)
(VALUE val)
/* This instruction typically has no funcalls. But it compares array
@@ -909,20 +909,21 @@ opt_newarray_max
* cannot but mark it being not leaf. */
// attr bool leaf = false; /* has rb_funcall() */
// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
-{
- val = vm_opt_newarray_max(ec, num, STACK_ADDR_FROM_TOP(num));
-}
-
-DEFINE_INSN
-opt_newarray_min
-(rb_num_t num)
-(...)
-(VALUE val)
-/* Same discussion as opt_newarray_max. */
-// attr bool leaf = false; /* has rb_funcall() */
-// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num;
-{
- val = vm_opt_newarray_min(ec, num, STACK_ADDR_FROM_TOP(num));
+// attr rb_snum_t comptime_sp_inc = 1 - (rb_snum_t)num;
+{
+ switch(method) {
+ case idHash:
+ val = vm_opt_newarray_hash(ec, num, STACK_ADDR_FROM_TOP(num));
+ break;
+ case idMin:
+ val = vm_opt_newarray_min(ec, num, STACK_ADDR_FROM_TOP(num));
+ break;
+ case idMax:
+ val = vm_opt_newarray_max(ec, num, STACK_ADDR_FROM_TOP(num));
+ break;
+ default:
+ rb_bug("unreachable");
+ }
}
/* super(args) # args.size => num */