Enable redefinition check for rbinc methods
This commit is contained in:
parent
1395838e18
commit
84d8dbe7a5
5
ruby.c
5
ruby.c
@ -1787,7 +1787,12 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
|
||||
|
||||
Init_ext(); /* load statically linked extensions before rubygems */
|
||||
Init_extra_exts();
|
||||
|
||||
GET_VM()->running = 0;
|
||||
rb_call_builtin_inits();
|
||||
GET_VM()->running = 1;
|
||||
memset(ruby_vm_redefined_flag, 0, sizeof(ruby_vm_redefined_flag));
|
||||
|
||||
ruby_init_prelude();
|
||||
|
||||
// Initialize JITs after prelude because JITing prelude is typically not optimal.
|
||||
|
78
vm.c
78
vm.c
@ -514,6 +514,8 @@ jit_exec_exception(rb_execution_context_t *ec)
|
||||
# define jit_exec_exception(ec) Qundef
|
||||
#endif
|
||||
|
||||
static void add_opt_method_entry(const rb_method_entry_t *me);
|
||||
|
||||
#include "vm_insnhelper.c"
|
||||
|
||||
#include "vm_exec.c"
|
||||
@ -2104,6 +2106,8 @@ vm_redefinition_check_method_type(const rb_method_entry_t *me)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (METHOD_ENTRY_BASIC(me)) return TRUE;
|
||||
|
||||
const rb_method_definition_t *def = me->def;
|
||||
switch (def->type) {
|
||||
case VM_METHOD_TYPE_CFUNC:
|
||||
@ -2154,27 +2158,44 @@ rb_vm_check_redefinition_by_prepend(VALUE klass)
|
||||
}
|
||||
|
||||
static void
|
||||
add_opt_method(VALUE klass, ID mid, VALUE bop)
|
||||
add_opt_method_entry_bop(const rb_method_entry_t *me, ID mid, enum ruby_basic_operators bop)
|
||||
{
|
||||
st_insert(vm_opt_method_def_table, (st_data_t)me->def, (st_data_t)bop);
|
||||
st_insert(vm_opt_mid_table, (st_data_t)mid, (st_data_t)Qtrue);
|
||||
}
|
||||
|
||||
static void
|
||||
add_opt_method(VALUE klass, ID mid, enum ruby_basic_operators bop)
|
||||
{
|
||||
const rb_method_entry_t *me = rb_method_entry_at(klass, mid);
|
||||
|
||||
if (me && vm_redefinition_check_method_type(me)) {
|
||||
st_insert(vm_opt_method_def_table, (st_data_t)me->def, (st_data_t)bop);
|
||||
st_insert(vm_opt_mid_table, (st_data_t)mid, (st_data_t)Qtrue);
|
||||
add_opt_method_entry_bop(me, mid, bop);
|
||||
}
|
||||
else {
|
||||
rb_bug("undefined optimized method: %s", rb_id2name(mid));
|
||||
}
|
||||
}
|
||||
|
||||
static enum ruby_basic_operators vm_redefinition_bop_for_id(ID mid);
|
||||
|
||||
static void
|
||||
add_opt_method_entry(const rb_method_entry_t *me)
|
||||
{
|
||||
if (me && vm_redefinition_check_method_type(me)) {
|
||||
ID mid = me->called_id;
|
||||
enum ruby_basic_operators bop = vm_redefinition_bop_for_id(mid);
|
||||
if ((int)bop >= 0) {
|
||||
add_opt_method_entry_bop(me, mid, bop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vm_init_redefined_flag(void)
|
||||
{
|
||||
ID mid;
|
||||
VALUE bop;
|
||||
|
||||
vm_opt_method_def_table = st_init_numtable();
|
||||
vm_opt_mid_table = st_init_numtable();
|
||||
enum ruby_basic_operators bop;
|
||||
|
||||
#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)
|
||||
@ -2213,6 +2234,46 @@ vm_init_redefined_flag(void)
|
||||
#undef OP
|
||||
}
|
||||
|
||||
static enum ruby_basic_operators
|
||||
vm_redefinition_bop_for_id(ID mid)
|
||||
{
|
||||
switch (mid) {
|
||||
#define OP(mid_, bop_) case id##mid_: return BOP_##bop_
|
||||
OP(PLUS, PLUS);
|
||||
OP(MINUS, MINUS);
|
||||
OP(MULT, MULT);
|
||||
OP(DIV, DIV);
|
||||
OP(MOD, MOD);
|
||||
OP(Eq, EQ);
|
||||
OP(Eqq, EQQ);
|
||||
OP(LT, LT);
|
||||
OP(LE, LE);
|
||||
OP(GT, GT);
|
||||
OP(GE, GE);
|
||||
OP(LTLT, LTLT);
|
||||
OP(AREF, AREF);
|
||||
OP(ASET, ASET);
|
||||
OP(Length, LENGTH);
|
||||
OP(Size, SIZE);
|
||||
OP(EmptyP, EMPTY_P);
|
||||
OP(Succ, SUCC);
|
||||
OP(EqTilde, MATCH);
|
||||
OP(Freeze, FREEZE);
|
||||
OP(UMinus, UMINUS);
|
||||
OP(Max, MAX);
|
||||
OP(Min, MIN);
|
||||
OP(Hash, HASH);
|
||||
OP(Call, CALL);
|
||||
OP(And, AND);
|
||||
OP(Or, OR);
|
||||
OP(NilP, NIL_P);
|
||||
OP(Cmp, CMP);
|
||||
OP(Default, DEFAULT);
|
||||
#undef OP
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* for vm development */
|
||||
|
||||
#if VMDEBUG
|
||||
@ -4213,6 +4274,9 @@ Init_BareVM(void)
|
||||
rb_native_mutex_initialize(&vm->ractor.sync.lock);
|
||||
rb_native_cond_initialize(&vm->ractor.sync.terminate_cond);
|
||||
|
||||
vm_opt_method_def_table = st_init_numtable();
|
||||
vm_opt_mid_table = st_init_numtable();
|
||||
|
||||
#ifdef RUBY_THREAD_WIN32_H
|
||||
rb_native_cond_initialize(&vm->ractor.sync.barrier_cond);
|
||||
#endif
|
||||
|
@ -522,6 +522,8 @@ rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *de
|
||||
rb_method_definition_release(me->def);
|
||||
*(rb_method_definition_t **)&me->def = method_definition_addref(def, METHOD_ENTRY_COMPLEMENTED(me));
|
||||
|
||||
if (!ruby_running) add_opt_method_entry(me);
|
||||
|
||||
if (opts != NULL) {
|
||||
switch (def->type) {
|
||||
case VM_METHOD_TYPE_ISEQ:
|
||||
|
Loading…
x
Reference in New Issue
Block a user