summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <[email protected]>2024-04-19 17:02:21 -0700
committerAaron Patterson <[email protected]>2024-04-24 09:30:59 -0700
commit853c0b1a776ba67cd20741f631788d8556c854eb ()
tree7ba1647c09ad03cc7428d5c4194d733ef625124d
parent9bba999be7b32949b4b37dd7a871c5dc1e36c2f8 (diff)
Reuse slow path method search for gccct
This way all code paths use the same search code for finding call caches for a particular method.
-rw-r--r--vm_eval.c86
-rw-r--r--vm_insnhelper.c4
-rw-r--r--vm_insnhelper.h8
3 files changed, 41 insertions, 57 deletions
@@ -29,15 +29,6 @@ static VALUE rb_eUncaughtThrow;
static ID id_result, id_tag, id_value;
#define id_mesg idMesg
-typedef enum call_type {
- CALL_PUBLIC,
- CALL_FCALL,
- CALL_VCALL,
- CALL_PUBLIC_KW,
- CALL_FCALL_KW,
- CALL_TYPE_MAX
-} call_type;
-
static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
static VALUE vm_call0_body(rb_execution_context_t* ec, struct rb_calling_info *calling, const VALUE *argv);
@@ -403,61 +394,46 @@ NORETURN(static void uncallable_object(VALUE recv, ID mid));
static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE recv, ID mid);
static inline enum method_missing_reason rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self);
-static const struct rb_callcache *
-cc_new(VALUE klass, ID mid, int argc, const rb_callable_method_entry_t *cme)
-{
- const struct rb_callcache *cc = NULL;
-
- RB_VM_LOCK_ENTER();
- {
- struct rb_class_cc_entries *ccs;
- struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
- VALUE ccs_data;
-
- if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
- // ok
- ccs = (struct rb_class_cc_entries *)ccs_data;
- }
- else {
- ccs = vm_ccs_create(klass, cc_tbl, mid, cme);
- }
-
- for (int i=0; i<ccs->len; i++) {
- cc = ccs->entries[i].cc;
- if (vm_cc_cme(cc) == cme) {
- break;
- }
- cc = NULL;
- }
-
- if (cc == NULL) {
- const struct rb_callinfo *ci = vm_ci_new(mid, 0, argc, NULL); // TODO: proper ci
- cc = vm_cc_new(klass, cme, vm_call_general, cc_type_normal);
- METHOD_ENTRY_CACHED_SET((struct rb_callable_method_entry_struct *)cme);
- vm_ccs_push(klass, ccs, ci, cc);
- }
- }
- RB_VM_LOCK_LEAVE();
-
- return cc;
-}
-
static VALUE
gccct_hash(VALUE klass, ID mid)
{
return (klass >> 3) ^ (VALUE)mid;
}
-NOINLINE(static const struct rb_callcache *gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, ID mid, int argc, unsigned int index));
static const struct rb_callcache *
-gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, ID mid, int argc, unsigned int index)
{
const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
const struct rb_callcache *cc;
if (cme != NULL) {
- cc = cc_new(klass, mid, argc, cme);
}
else {
cc = NULL;
@@ -467,7 +443,7 @@ gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, ID mid, int argc, unsigne
}
static inline const struct rb_callcache *
-gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, int argc)
{
VALUE klass;
@@ -502,7 +478,7 @@ gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, int argc)
}
RB_DEBUG_COUNTER_INC(gccct_miss);
- return gccct_method_search_slowpath(vm, klass, mid, argc, index);
}
/**
@@ -543,7 +519,7 @@ rb_call0(rb_execution_context_t *ec,
break;
}
- const struct rb_callcache *cc = gccct_method_search(ec, recv, mid, argc);
if (scope == CALL_PUBLIC) {
RB_DEBUG_COUNTER_INC(call0_public);
@@ -1060,7 +1036,7 @@ static inline VALUE
rb_funcallv_scope(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope)
{
rb_execution_context_t *ec = GET_EC();
- const struct rb_callcache *cc = gccct_method_search(ec, recv, mid, argc);
VALUE self = ec->cfp->self;
if (LIKELY(cc) &&
@@ -2421,13 +2421,13 @@ opt_equality(const rb_iseq_t *cd_owner, VALUE recv, VALUE obj, CALL_DATA cd)
#undef EQ_UNREDEFINED_P
-static inline const struct rb_callcache *gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, int argc); // vm_eval.c
NOINLINE(static VALUE opt_equality_by_mid_slowpath(VALUE recv, VALUE obj, ID mid));
static VALUE
opt_equality_by_mid_slowpath(VALUE recv, VALUE obj, ID mid)
{
- const struct rb_callcache *cc = gccct_method_search(GET_EC(), recv, mid, 1);
if (cc && check_cfunc(vm_cc_cme(cc), rb_obj_equal)) {
return RBOOL(recv == obj);
@@ -58,6 +58,14 @@ RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state;
VM_REG_CFP = ec->cfp; \
} while (0)
#if VM_COLLECT_USAGE_DETAILS
enum vm_regan_regtype {
VM_REGAN_PC = 0,