From 7afabb8e93d6b8620604025733a47eec68c582ac Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 3 Dec 2015 11:17:35 -0800 Subject: [PATCH 2/2] add a tracepoint for PIC hit / miss --- include/ruby/ruby.h | 2 ++ vm_insnhelper.c | 8 ++++++++ vm_trace.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index e7f2f0d..f14a516 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -2060,6 +2060,8 @@ int ruby_native_thread_p(void); #define RUBY_EVENT_THREAD_BEGIN 0x0400 #define RUBY_EVENT_THREAD_END 0x0800 #define RUBY_EVENT_FIBER_SWITCH 0x1000 +#define RUBY_EVENT_INLINE_CACHE_HIT 0x2000 +#define RUBY_EVENT_INLINE_CACHE_MISS 0x4000 #define RUBY_EVENT_TRACEPOINT_ALL 0xffff /* special events */ diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 8692b7a..09a8fb2 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1124,7 +1124,11 @@ vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE #if OPT_INLINE_METHOD_CACHE int i; + rb_thread_t *th = GET_THREAD(); + VALUE ccid; if (LIKELY(GET_GLOBAL_METHOD_STATE() == cc->method_state && RCLASS_SERIAL(klass) == cc->class_serial)) { + ccid = INT2NUM(cc); + EXEC_EVENT_HOOK(th, RUBY_EVENT_INLINE_CACHE_HIT, recv, 0, 0, ccid); /* cache hit! */ return; # if OPT_POLYMORPHIC_INLINE_METHOD_CACHE @@ -1137,6 +1141,8 @@ vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE cc->me = cc->mes[i]; cc->class_serial = cc->class_serials[i]; cc->call = cc->calls[i]; + ccid = INT2NUM(cc); + EXEC_EVENT_HOOK(th, RUBY_EVENT_INLINE_CACHE_HIT, recv, 0, 0, ccid); /* cache hit! */ return; } @@ -1156,6 +1162,8 @@ vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE VM_ASSERT(callable_method_entry_p(cc->me)); cc->call = vm_call_general; #if OPT_INLINE_METHOD_CACHE + ccid = INT2NUM(cc); + EXEC_EVENT_HOOK(th, RUBY_EVENT_INLINE_CACHE_MISS, recv, 0, 0, ccid); cc->method_state = GET_GLOBAL_METHOD_STATE(); cc->class_serial = RCLASS_SERIAL(klass); diff --git a/vm_trace.c b/vm_trace.c index 0515abf..4da76e8 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -598,6 +598,8 @@ get_event_id(rb_event_flag_t event) C(thread_end, THREAD_END); C(fiber_switch, FIBER_SWITCH); C(specified_line, SPECIFIED_LINE); + C(inline_cache_hit, INLINE_CACHE_HIT); + C(inline_cache_miss, INLINE_CACHE_MISS); case RUBY_EVENT_LINE | RUBY_EVENT_SPECIFIED_LINE: CONST_ID(id, "line"); return id; #undef C default: @@ -706,6 +708,8 @@ symbol2event_flag(VALUE v) C(specified_line, SPECIFIED_LINE); C(a_call, A_CALL); C(a_return, A_RETURN); + C(inline_cache_hit, INLINE_CACHE_HIT); + C(inline_cache_miss, INLINE_CACHE_MISS); #undef C rb_raise(rb_eArgError, "unknown event: %"PRIsVALUE, rb_sym2str(sym)); } @@ -832,6 +836,21 @@ rb_tracearg_self(rb_trace_arg_t *trace_arg) } VALUE +rb_tracearg_callcache_id(rb_trace_arg_t *trace_arg) +{ + if (trace_arg->event & (RUBY_EVENT_INLINE_CACHE_HIT | RUBY_EVENT_INLINE_CACHE_MISS)) { + /* ok */ + } + else { + rb_raise(rb_eRuntimeError, "not supported by this event"); + } + if (trace_arg->data == Qundef) { + rb_bug("tp_attr_return_value_m: unreachable"); + } + return trace_arg->data; +} + +VALUE rb_tracearg_return_value(rb_trace_arg_t *trace_arg) { if (trace_arg->event & (RUBY_EVENT_RETURN | RUBY_EVENT_C_RETURN | RUBY_EVENT_B_RETURN)) { @@ -985,6 +1004,16 @@ tracepoint_attr_return_value(VALUE tpval) } /* + * Return call cache id for +:inline_cache_hit+ and +:inline_cache_miss+ + */ +static VALUE +tracepoint_callcache_id(VALUE tpval) +{ + return rb_tracearg_callcache_id(get_trace_arg()); +} + + +/* * Value from exception raised on the +:raise+ event */ static VALUE @@ -1485,6 +1514,7 @@ Init_vm_trace(void) rb_define_method(rb_cTracePoint, "self", tracepoint_attr_self, 0); rb_define_method(rb_cTracePoint, "return_value", tracepoint_attr_return_value, 0); rb_define_method(rb_cTracePoint, "raised_exception", tracepoint_attr_raised_exception, 0); + rb_define_method(rb_cTracePoint, "callcache_id", tracepoint_callcache_id, 0); rb_define_singleton_method(rb_cTracePoint, "stat", tracepoint_stat_s, 0); -- 2.2.1