diff options
author | John Hawthorn <john@hawthorn.email> | 2019-12-12 15:47:59 -0800 |
---|---|---|
committer | Aaron Patterson <tenderlove@github.com> | 2019-12-17 09:19:00 -0800 |
commit | 254477248cde5bf82c4f256dca05b13d01c9774c (patch) | |
tree | 84e9676862da8fb830ef89f18dd5907d0d4c5508 /vm.c | |
parent | 9245462499e7c3216a468aadccdc11e69de8cd54 (diff) |
Skip optimized method check for most method IDs
Previously every time a method was defined on a module, we would
recursively walk all subclasses to see if the module was included in a
class which the VM optimizes for (such as Integer#+).
For most method definitions we can tell immediately that this won't be
the case based on the method's name. To do this we just keep a hash with
method IDs of optimized methods and if our new method isn't in that list
we don't need to check subclasses at all.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/2752
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 13 |
1 files changed, 13 insertions, 0 deletions
@@ -1557,6 +1557,7 @@ rb_iter_break_value(VALUE val) /* optimization: redefine management */ static st_table *vm_opt_method_table = 0; +static st_table *vm_opt_mid_table = 0; static int vm_redefinition_check_flag(VALUE klass) @@ -1576,6 +1577,16 @@ vm_redefinition_check_flag(VALUE klass) return 0; } +int +rb_vm_check_optimizable_mid(VALUE mid) +{ + if (!vm_opt_mid_table) { + return FALSE; + } + + return st_lookup(vm_opt_mid_table, mid, NULL); +} + static int vm_redefinition_check_method_type(const rb_method_definition_t *def) { @@ -1630,6 +1641,7 @@ add_opt_method(VALUE klass, ID mid, VALUE bop) if (me && vm_redefinition_check_method_type(me->def)) { st_insert(vm_opt_method_table, (st_data_t)me, (st_data_t)bop); + st_insert(vm_opt_mid_table, (st_data_t)mid, (st_data_t)Qtrue); } else { rb_bug("undefined optimized method: %s", rb_id2name(mid)); @@ -1643,6 +1655,7 @@ vm_init_redefined_flag(void) VALUE bop; vm_opt_method_table = st_init_numtable(); + vm_opt_mid_table = st_init_numtable(); #define OP(mid_, bop_) (mid = id##mid_, bop = BOP_##bop_, ruby_vm_redefined_flag[bop] = 0) #define C(k) add_opt_method(rb_c##k, mid, bop) |