diff options
author | Jeremy Evans <code@jeremyevans.net> | 2021-09-30 13:18:14 -0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-30 15:18:14 -0700 |
commit | 1f5f8a187adb746b01cc95c3f29a0a355f513374 (patch) | |
tree | 9d907b527d60b89f4c9d6402b1bdabb8aec7abf0 /vm_insnhelper.c | |
parent | a55a5fc68426ed701dace6bc166d18de06d8dcb2 (diff) |
Make Array#min/max optimization respect refined methods
Pass in ec to vm_opt_newarray_{max,min}. Avoids having to
call GET_EC inside the functions, for better performance.
While here, add a test for Array#min/max being redefined to
test_optimization.rb.
Fixes [Bug #18180]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4911
Merged-By: jeremyevans <code@jeremyevans.net>
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index bbb62d8397..d4740ecc4e 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -4655,7 +4655,7 @@ vm_opt_str_freeze(VALUE str, int bop, ID id) #define id_cmp idCmp static VALUE -vm_opt_newarray_max(rb_num_t num, const VALUE *ptr) +vm_opt_newarray_max(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr) { if (BASIC_OP_UNREDEFINED_P(BOP_MAX, ARRAY_REDEFINED_OP_FLAG)) { if (num == 0) { @@ -4676,12 +4676,19 @@ vm_opt_newarray_max(rb_num_t num, const VALUE *ptr) } else { VALUE ary = rb_ary_new4(num, ptr); - return rb_funcall(ary, idMax, 0); + const rb_callable_method_entry_t *me = + rb_callable_method_entry_with_refinements(rb_cArray, idMax, NULL); + if (me) { + return rb_vm_call0(ec, ary, idMax, 0, NULL, me, RB_NO_KEYWORDS); + } + else { + return rb_funcall(ary, idMax, 0); + } } } static VALUE -vm_opt_newarray_min(rb_num_t num, const VALUE *ptr) +vm_opt_newarray_min(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr) { if (BASIC_OP_UNREDEFINED_P(BOP_MIN, ARRAY_REDEFINED_OP_FLAG)) { if (num == 0) { @@ -4702,7 +4709,14 @@ vm_opt_newarray_min(rb_num_t num, const VALUE *ptr) } else { VALUE ary = rb_ary_new4(num, ptr); - return rb_funcall(ary, idMin, 0); + const rb_callable_method_entry_t *me = + rb_callable_method_entry_with_refinements(rb_cArray, idMin, NULL); + if (me) { + return rb_vm_call0(ec, ary, idMin, 0, NULL, me, RB_NO_KEYWORDS); + } + else { + return rb_funcall(ary, idMin, 0); + } } } |