From e2a45cb984ba75083a577b38ee9643800579a280 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Thu, 7 Nov 2019 18:22:08 +0900 Subject: use builtin for TracePoint. Define TracePoint in trace_point.rb and use __builtin_ syntax. --- vm_trace.c | 338 +++++++------------------------------------------------------ 1 file changed, 36 insertions(+), 302 deletions(-) (limited to 'vm_trace.c') diff --git a/vm_trace.c b/vm_trace.c index eb1c2afa4e..1cb5fd0036 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -28,6 +28,7 @@ #include "mjit.h" #include "iseq.h" #include "eval_intern.h" +#include "builtin.h" /* (1) trace mechanisms */ @@ -1018,160 +1019,79 @@ rb_tracearg_object(rb_trace_arg_t *trace_arg) return trace_arg->data; } -/* - * Type of event - * - * See TracePoint@Events for more information. - */ static VALUE -tracepoint_attr_event(VALUE tpval) +tracepoint_attr_event(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_event(get_trace_arg()); } -/* - * Line number of the event - */ static VALUE -tracepoint_attr_lineno(VALUE tpval) +tracepoint_attr_lineno(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_lineno(get_trace_arg()); } - -/* - * Path of the file being run - */ static VALUE -tracepoint_attr_path(VALUE tpval) +tracepoint_attr_path(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_path(get_trace_arg()); } -/* - * Return the parameters definition of the method or block that the - * current hook belongs to. Format is the same as for Method#parameters - */ static VALUE -tracepoint_attr_parameters(VALUE tpval) +tracepoint_attr_parameters(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_parameters(get_trace_arg()); } -/* - * Return the name at the definition of the method being called - */ static VALUE -tracepoint_attr_method_id(VALUE tpval) +tracepoint_attr_method_id(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_method_id(get_trace_arg()); } -/* - * Return the called name of the method being called - */ static VALUE -tracepoint_attr_callee_id(VALUE tpval) +tracepoint_attr_callee_id(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_callee_id(get_trace_arg()); } -/* - * Return class or module of the method being called. - * - * class C; def foo; end; end - * trace = TracePoint.new(:call) do |tp| - * p tp.defined_class #=> C - * end.enable do - * C.new.foo - * end - * - * If method is defined by a module, then that module is returned. - * - * module M; def foo; end; end - * class C; include M; end; - * trace = TracePoint.new(:call) do |tp| - * p tp.defined_class #=> M - * end.enable do - * C.new.foo - * end - * - * Note: #defined_class returns singleton class. - * - * 6th block parameter of Kernel#set_trace_func passes original class - * of attached by singleton class. - * - * This is a difference between Kernel#set_trace_func and TracePoint. - * - * class C; def self.foo; end; end - * trace = TracePoint.new(:call) do |tp| - * p tp.defined_class #=> # - * end.enable do - * C.foo - * end - */ static VALUE -tracepoint_attr_defined_class(VALUE tpval) +tracepoint_attr_defined_class(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_defined_class(get_trace_arg()); } -/* - * Return the generated binding object from event - */ static VALUE -tracepoint_attr_binding(VALUE tpval) +tracepoint_attr_binding(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_binding(get_trace_arg()); } -/* - * Return the trace object during event - * - * Same as TracePoint#binding: - * trace.binding.eval('self') - */ static VALUE -tracepoint_attr_self(VALUE tpval) +tracepoint_attr_self(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_self(get_trace_arg()); } -/* - * Return value from +:return+, +c_return+, and +b_return+ event - */ static VALUE -tracepoint_attr_return_value(VALUE tpval) +tracepoint_attr_return_value(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_return_value(get_trace_arg()); } -/* - * Value from exception raised on the +:raise+ event - */ static VALUE -tracepoint_attr_raised_exception(VALUE tpval) +tracepoint_attr_raised_exception(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_raised_exception(get_trace_arg()); } -/* - * Compiled source code (String) on *eval methods on the +:script_compiled+ event. - * If loaded from a file, it will return nil. - */ static VALUE -tracepoint_attr_eval_script(VALUE tpval) +tracepoint_attr_eval_script(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_eval_script(get_trace_arg()); } -/* - * Compiled instruction sequence represented by a RubyVM::InstructionSequence instance - * on the +:script_compiled+ event. - * - * Note that this method is MRI specific. - */ static VALUE -tracepoint_attr_instruction_sequence(VALUE tpval) +tracepoint_attr_instruction_sequence(rb_execution_context_t *ec, VALUE tpval) { return rb_tracearg_instruction_sequence(get_trace_arg()); } @@ -1352,11 +1272,8 @@ rb_hook_list_remove_tracepoint(rb_hook_list_t *list, VALUE tpval) list->events = events; } -/* :nodoc: - * Docs for the TracePointe#enable are in prelude.rb - */ static VALUE -tracepoint_enable_m(VALUE tpval, VALUE target, VALUE target_line, VALUE target_thread) +tracepoint_enable_m(rb_execution_context_t *ec, VALUE tpval, VALUE target, VALUE target_line, VALUE target_thread) { rb_tp_t *tp = tpptr(tpval); int previous_tracing = tp->tracing; @@ -1392,43 +1309,8 @@ tracepoint_enable_m(VALUE tpval, VALUE target, VALUE target_line, VALUE target_t } } -/* - * call-seq: - * trace.disable -> true or false - * trace.disable { block } -> obj - * - * Deactivates the trace - * - * Return true if trace was enabled. - * Return false if trace was disabled. - * - * trace.enabled? #=> true - * trace.disable #=> true (previous status) - * trace.enabled? #=> false - * trace.disable #=> false - * - * If a block is given, the trace will only be disable within the scope of the - * block. - * - * trace.enabled? - * #=> true - * - * trace.disable do - * trace.enabled? - * # only disabled for this block - * end - * - * trace.enabled? - * #=> true - * - * Note: You cannot access event hooks within the block. - * - * trace.disable { p tp.lineno } - * #=> RuntimeError: access from outside - */ - static VALUE -tracepoint_disable_m(VALUE tpval) +tracepoint_disable_m(rb_execution_context_t *ec, VALUE tpval) { rb_tp_t *tp = tpptr(tpval); int previous_tracing = tp->tracing; @@ -1449,12 +1331,6 @@ tracepoint_disable_m(VALUE tpval) } } -/* - * call-seq: - * trace.enabled? -> true or false - * - * The current status of the trace - */ VALUE rb_tracepoint_enabled_p(VALUE tpval) { @@ -1462,6 +1338,12 @@ rb_tracepoint_enabled_p(VALUE tpval) return tp->tracing ? Qtrue : Qfalse; } +static VALUE +tracepoint_enabled_p(rb_execution_context_t *ec, VALUE tpval) +{ + return rb_tracepoint_enabled_p(tpval); +} + static VALUE tracepoint_new(VALUE klass, rb_thread_t *target_th, rb_event_flag_t events, void (func)(VALUE, void*), void *data, VALUE proc) { @@ -1522,63 +1404,17 @@ rb_tracepoint_new(VALUE target_thval, rb_event_flag_t events, void (*func)(VALUE return tracepoint_new(rb_cTracePoint, target_th, events, func, data, Qundef); } -/* - * call-seq: - * TracePoint.new(*events) { |obj| block } -> obj - * - * Returns a new TracePoint object, not enabled by default. - * - * Next, in order to activate the trace, you must use TracePoint#enable - * - * trace = TracePoint.new(:call) do |tp| - * p [tp.lineno, tp.defined_class, tp.method_id, tp.event] - * end - * #=> # - * - * trace.enable - * #=> false - * - * puts "Hello, TracePoint!" - * # ... - * # [48, IRB::Notifier::AbstractNotifier, :printf, :call] - * # ... - * - * When you want to deactivate the trace, you must use TracePoint#disable - * - * trace.disable - * - * See TracePoint@Events for possible events and more information. - * - * A block must be given, otherwise an ArgumentError is raised. - * - * If the trace method isn't included in the given events filter, a - * RuntimeError is raised. - * - * TracePoint.trace(:line) do |tp| - * p tp.raised_exception - * end - * #=> RuntimeError: 'raised_exception' not supported by this event - * - * If the trace method is called outside block, a RuntimeError is raised. - * - * TracePoint.trace(:line) do |tp| - * $tp = tp - * end - * $tp.lineno #=> access from outside (RuntimeError) - * - * Access from other threads is also forbidden. - * - */ static VALUE -tracepoint_new_s(int argc, VALUE *argv, VALUE self) +tracepoint_new_s(rb_execution_context_t *ec, VALUE self, VALUE args) { rb_event_flag_t events = 0; - int i; + long i; + long argc = RARRAY_LEN(args); if (argc > 0) { - for (i=0; i string - * - * Return a string containing a human-readable TracePoint - * status. - */ - static VALUE -tracepoint_inspect(VALUE self) +tracepoint_inspect(rb_execution_context_t *ec, VALUE self) { rb_tp_t *tp = tpptr(self); rb_trace_arg_t *trace_arg = GET_EC()->trace_arg; @@ -1671,20 +1499,8 @@ tracepoint_stat_event_hooks(VALUE hash, VALUE key, rb_event_hook_t *hook) rb_hash_aset(hash, key, rb_ary_new3(2, INT2FIX(active), INT2FIX(deleted))); } -/* - * call-seq: - * TracePoint.stat -> obj - * - * Returns internal information of TracePoint. - * - * The contents of the returned value are implementation specific. - * It may be changed in future. - * - * This method is only for debugging TracePoint itself. - */ - static VALUE -tracepoint_stat_s(VALUE self) +tracepoint_stat_s(rb_execution_context_t *ec, VALUE self) { rb_vm_t *vm = GET_VM(); VALUE stat = rb_hash_new(); @@ -1695,6 +1511,8 @@ tracepoint_stat_s(VALUE self) return stat; } +#include "load_trace_point.inc" + /* This function is called from inits.c */ void Init_vm_trace(void) @@ -1704,94 +1522,10 @@ Init_vm_trace(void) rb_define_method(rb_cThread, "set_trace_func", thread_set_trace_func_m, 1); rb_define_method(rb_cThread, "add_trace_func", thread_add_trace_func_m, 1); - /* - * Document-class: TracePoint - * - * A class that provides the functionality of Kernel#set_trace_func in a - * nice Object-Oriented API. - * - * == Example - * - * We can use TracePoint to gather information specifically for exceptions: - * - * trace = TracePoint.new(:raise) do |tp| - * p [tp.lineno, tp.event, tp.raised_exception] - * end - * #=> # - * - * trace.enable - * #=> false - * - * 0 / 0 - * #=> [5, :raise, #] - * - * == Events - * - * If you don't specify the type of events you want to listen for, - * TracePoint will include all available events. - * - * *Note* do not depend on current event set, as this list is subject to - * change. Instead, it is recommended you specify the type of events you - * want to use. - * - * To filter what is traced, you can pass any of the following as +events+: - * - * +:line+:: execute code on a new line - * +:class+:: start a class or module definition - * +:end+:: finish a class or module definition - * +:call+:: call a Ruby method - * +:return+:: return from a Ruby method - * +:c_call+:: call a C-language routine - * +:c_return+:: return from a C-language routine - * +:raise+:: raise an exception - * +:b_call+:: event hook at block entry - * +:b_return+:: event hook at block ending - * +:thread_begin+:: event hook at thread beginning - * +:thread_end+:: event hook at thread ending - * +:fiber_switch+:: event hook at fiber switch - * +:script_compiled+:: new Ruby code compiled (with +eval+, +load+ or +require+) - * - */ rb_cTracePoint = rb_define_class("TracePoint", rb_cObject); rb_undef_alloc_func(rb_cTracePoint); - rb_define_singleton_method(rb_cTracePoint, "new", tracepoint_new_s, -1); - /* - * Document-method: trace - * - * call-seq: - * TracePoint.trace(*events) { |obj| block } -> obj - * - * A convenience method for TracePoint.new, that activates the trace - * automatically. - * - * trace = TracePoint.trace(:call) { |tp| [tp.lineno, tp.event] } - * #=> # - * - * trace.enabled? #=> true - */ - rb_define_singleton_method(rb_cTracePoint, "trace", tracepoint_trace_s, -1); - - rb_define_method(rb_cTracePoint, "__enable", tracepoint_enable_m, 3); - rb_define_method(rb_cTracePoint, "disable", tracepoint_disable_m, 0); - rb_define_method(rb_cTracePoint, "enabled?", rb_tracepoint_enabled_p, 0); - - rb_define_method(rb_cTracePoint, "inspect", tracepoint_inspect, 0); - - rb_define_method(rb_cTracePoint, "event", tracepoint_attr_event, 0); - rb_define_method(rb_cTracePoint, "lineno", tracepoint_attr_lineno, 0); - rb_define_method(rb_cTracePoint, "path", tracepoint_attr_path, 0); - rb_define_method(rb_cTracePoint, "parameters", tracepoint_attr_parameters, 0); - rb_define_method(rb_cTracePoint, "method_id", tracepoint_attr_method_id, 0); - rb_define_method(rb_cTracePoint, "callee_id", tracepoint_attr_callee_id, 0); - rb_define_method(rb_cTracePoint, "defined_class", tracepoint_attr_defined_class, 0); - rb_define_method(rb_cTracePoint, "binding", tracepoint_attr_binding, 0); - 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, "eval_script", tracepoint_attr_eval_script, 0); - rb_define_method(rb_cTracePoint, "instruction_sequence", tracepoint_attr_instruction_sequence, 0); - - rb_define_singleton_method(rb_cTracePoint, "stat", tracepoint_stat_s, 0); + + load_trace_point(); } typedef struct rb_postponed_job_struct { -- cgit v1.2.3