Skip to content

Commit 84d8dbe

Browse files
nobutenderlove
authored andcommitted
Enable redefinition check for rbinc methods
1 parent 1395838 commit 84d8dbe

File tree

3 files changed

+78
-7
lines changed

3 files changed

+78
-7
lines changed

ruby.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,7 +1787,12 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
17871787

17881788
Init_ext(); /* load statically linked extensions before rubygems */
17891789
Init_extra_exts();
1790+
1791+
GET_VM()->running = 0;
17901792
rb_call_builtin_inits();
1793+
GET_VM()->running = 1;
1794+
memset(ruby_vm_redefined_flag, 0, sizeof(ruby_vm_redefined_flag));
1795+
17911796
ruby_init_prelude();
17921797

17931798
// Initialize JITs after prelude because JITing prelude is typically not optimal.

vm.c

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ jit_exec_exception(rb_execution_context_t *ec)
514514
# define jit_exec_exception(ec) Qundef
515515
#endif
516516

517+
static void add_opt_method_entry(const rb_method_entry_t *me);
518+
517519
#include "vm_insnhelper.c"
518520

519521
#include "vm_exec.c"
@@ -2104,6 +2106,8 @@ vm_redefinition_check_method_type(const rb_method_entry_t *me)
21042106
return FALSE;
21052107
}
21062108

2109+
if (METHOD_ENTRY_BASIC(me)) return TRUE;
2110+
21072111
const rb_method_definition_t *def = me->def;
21082112
switch (def->type) {
21092113
case VM_METHOD_TYPE_CFUNC:
@@ -2154,27 +2158,44 @@ rb_vm_check_redefinition_by_prepend(VALUE klass)
21542158
}
21552159

21562160
static void
2157-
add_opt_method(VALUE klass, ID mid, VALUE bop)
2161+
add_opt_method_entry_bop(const rb_method_entry_t *me, ID mid, enum ruby_basic_operators bop)
2162+
{
2163+
st_insert(vm_opt_method_def_table, (st_data_t)me->def, (st_data_t)bop);
2164+
st_insert(vm_opt_mid_table, (st_data_t)mid, (st_data_t)Qtrue);
2165+
}
2166+
2167+
static void
2168+
add_opt_method(VALUE klass, ID mid, enum ruby_basic_operators bop)
21582169
{
21592170
const rb_method_entry_t *me = rb_method_entry_at(klass, mid);
21602171

21612172
if (me && vm_redefinition_check_method_type(me)) {
2162-
st_insert(vm_opt_method_def_table, (st_data_t)me->def, (st_data_t)bop);
2163-
st_insert(vm_opt_mid_table, (st_data_t)mid, (st_data_t)Qtrue);
2173+
add_opt_method_entry_bop(me, mid, bop);
21642174
}
21652175
else {
21662176
rb_bug("undefined optimized method: %s", rb_id2name(mid));
21672177
}
21682178
}
21692179

2180+
static enum ruby_basic_operators vm_redefinition_bop_for_id(ID mid);
2181+
2182+
static void
2183+
add_opt_method_entry(const rb_method_entry_t *me)
2184+
{
2185+
if (me && vm_redefinition_check_method_type(me)) {
2186+
ID mid = me->called_id;
2187+
enum ruby_basic_operators bop = vm_redefinition_bop_for_id(mid);
2188+
if ((int)bop >= 0) {
2189+
add_opt_method_entry_bop(me, mid, bop);
2190+
}
2191+
}
2192+
}
2193+
21702194
static void
21712195
vm_init_redefined_flag(void)
21722196
{
21732197
ID mid;
2174-
VALUE bop;
2175-
2176-
vm_opt_method_def_table = st_init_numtable();
2177-
vm_opt_mid_table = st_init_numtable();
2198+
enum ruby_basic_operators bop;
21782199

21792200
#define OP(mid_, bop_) (mid = id##mid_, bop = BOP_##bop_, ruby_vm_redefined_flag[bop] = 0)
21802201
#define C(k) add_opt_method(rb_c##k, mid, bop)
@@ -2213,6 +2234,46 @@ vm_init_redefined_flag(void)
22132234
#undef OP
22142235
}
22152236

2237+
static enum ruby_basic_operators
2238+
vm_redefinition_bop_for_id(ID mid)
2239+
{
2240+
switch (mid) {
2241+
#define OP(mid_, bop_) case id##mid_: return BOP_##bop_
2242+
OP(PLUS, PLUS);
2243+
OP(MINUS, MINUS);
2244+
OP(MULT, MULT);
2245+
OP(DIV, DIV);
2246+
OP(MOD, MOD);
2247+
OP(Eq, EQ);
2248+
OP(Eqq, EQQ);
2249+
OP(LT, LT);
2250+
OP(LE, LE);
2251+
OP(GT, GT);
2252+
OP(GE, GE);
2253+
OP(LTLT, LTLT);
2254+
OP(AREF, AREF);
2255+
OP(ASET, ASET);
2256+
OP(Length, LENGTH);
2257+
OP(Size, SIZE);
2258+
OP(EmptyP, EMPTY_P);
2259+
OP(Succ, SUCC);
2260+
OP(EqTilde, MATCH);
2261+
OP(Freeze, FREEZE);
2262+
OP(UMinus, UMINUS);
2263+
OP(Max, MAX);
2264+
OP(Min, MIN);
2265+
OP(Hash, HASH);
2266+
OP(Call, CALL);
2267+
OP(And, AND);
2268+
OP(Or, OR);
2269+
OP(NilP, NIL_P);
2270+
OP(Cmp, CMP);
2271+
OP(Default, DEFAULT);
2272+
#undef OP
2273+
}
2274+
return -1;
2275+
}
2276+
22162277
/* for vm development */
22172278

22182279
#if VMDEBUG
@@ -4213,6 +4274,9 @@ Init_BareVM(void)
42134274
rb_native_mutex_initialize(&vm->ractor.sync.lock);
42144275
rb_native_cond_initialize(&vm->ractor.sync.terminate_cond);
42154276

4277+
vm_opt_method_def_table = st_init_numtable();
4278+
vm_opt_mid_table = st_init_numtable();
4279+
42164280
#ifdef RUBY_THREAD_WIN32_H
42174281
rb_native_cond_initialize(&vm->ractor.sync.barrier_cond);
42184282
#endif

vm_method.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *de
522522
rb_method_definition_release(me->def);
523523
*(rb_method_definition_t **)&me->def = method_definition_addref(def, METHOD_ENTRY_COMPLEMENTED(me));
524524

525+
if (!ruby_running) add_opt_method_entry(me);
526+
525527
if (opts != NULL) {
526528
switch (def->type) {
527529
case VM_METHOD_TYPE_ISEQ:

0 commit comments

Comments
 (0)