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_ext(); /* load statically linked extensions before rubygems */
|
||||||
Init_extra_exts();
|
Init_extra_exts();
|
||||||
|
|
||||||
|
GET_VM()->running = 0;
|
||||||
rb_call_builtin_inits();
|
rb_call_builtin_inits();
|
||||||
|
GET_VM()->running = 1;
|
||||||
|
memset(ruby_vm_redefined_flag, 0, sizeof(ruby_vm_redefined_flag));
|
||||||
|
|
||||||
ruby_init_prelude();
|
ruby_init_prelude();
|
||||||
|
|
||||||
// Initialize JITs after prelude because JITing prelude is typically not optimal.
|
// 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
|
# define jit_exec_exception(ec) Qundef
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void add_opt_method_entry(const rb_method_entry_t *me);
|
||||||
|
|
||||||
#include "vm_insnhelper.c"
|
#include "vm_insnhelper.c"
|
||||||
|
|
||||||
#include "vm_exec.c"
|
#include "vm_exec.c"
|
||||||
@ -2104,6 +2106,8 @@ vm_redefinition_check_method_type(const rb_method_entry_t *me)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (METHOD_ENTRY_BASIC(me)) return TRUE;
|
||||||
|
|
||||||
const rb_method_definition_t *def = me->def;
|
const rb_method_definition_t *def = me->def;
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
case VM_METHOD_TYPE_CFUNC:
|
case VM_METHOD_TYPE_CFUNC:
|
||||||
@ -2154,27 +2158,44 @@ rb_vm_check_redefinition_by_prepend(VALUE klass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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);
|
const rb_method_entry_t *me = rb_method_entry_at(klass, mid);
|
||||||
|
|
||||||
if (me && vm_redefinition_check_method_type(me)) {
|
if (me && vm_redefinition_check_method_type(me)) {
|
||||||
st_insert(vm_opt_method_def_table, (st_data_t)me->def, (st_data_t)bop);
|
add_opt_method_entry_bop(me, mid, bop);
|
||||||
st_insert(vm_opt_mid_table, (st_data_t)mid, (st_data_t)Qtrue);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rb_bug("undefined optimized method: %s", rb_id2name(mid));
|
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
|
static void
|
||||||
vm_init_redefined_flag(void)
|
vm_init_redefined_flag(void)
|
||||||
{
|
{
|
||||||
ID mid;
|
ID mid;
|
||||||
VALUE bop;
|
enum ruby_basic_operators bop;
|
||||||
|
|
||||||
vm_opt_method_def_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 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)
|
#define C(k) add_opt_method(rb_c##k, mid, bop)
|
||||||
@ -2213,6 +2234,46 @@ vm_init_redefined_flag(void)
|
|||||||
#undef OP
|
#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 */
|
/* for vm development */
|
||||||
|
|
||||||
#if VMDEBUG
|
#if VMDEBUG
|
||||||
@ -4213,6 +4274,9 @@ Init_BareVM(void)
|
|||||||
rb_native_mutex_initialize(&vm->ractor.sync.lock);
|
rb_native_mutex_initialize(&vm->ractor.sync.lock);
|
||||||
rb_native_cond_initialize(&vm->ractor.sync.terminate_cond);
|
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
|
#ifdef RUBY_THREAD_WIN32_H
|
||||||
rb_native_cond_initialize(&vm->ractor.sync.barrier_cond);
|
rb_native_cond_initialize(&vm->ractor.sync.barrier_cond);
|
||||||
#endif
|
#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_release(me->def);
|
||||||
*(rb_method_definition_t **)&me->def = method_definition_addref(def, METHOD_ENTRY_COMPLEMENTED(me));
|
*(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) {
|
if (opts != NULL) {
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
case VM_METHOD_TYPE_ISEQ:
|
case VM_METHOD_TYPE_ISEQ:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user