summaryrefslogtreecommitdiff
path: root/vm_trace.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2019-11-07 18:22:08 +0900
committerKoichi Sasada <ko1@atdot.net>2019-11-08 09:09:29 +0900
commite2a45cb984ba75083a577b38ee9643800579a280 (patch)
tree9e8c56b3c7081b3ffdd8b65ca16c166ba186725e /vm_trace.c
parent46acd0075d80c2f886498f089fde1e9d795d50c4 (diff)
use builtin for TracePoint.
Define TracePoint in trace_point.rb and use __builtin_ syntax.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/2655
Diffstat (limited to 'vm_trace.c')
-rw-r--r--vm_trace.c338
1 files changed, 36 insertions, 302 deletions
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
- *
- * <b>Note:</b> #defined_class returns singleton class.
- *
- * 6th block parameter of Kernel#set_trace_func passes original class
- * of attached by singleton class.
- *
- * <b>This is a difference between Kernel#set_trace_func and TracePoint.</b>
- *
- * class C; def self.foo; end; end
- * trace = TracePoint.new(:call) do |tp|
- * p tp.defined_class #=> #<Class:C>
- * 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)
{
@@ -1463,6 +1339,12 @@ rb_tracepoint_enabled_p(VALUE tpval)
}
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)
{
VALUE tpval = tp_alloc(klass);
@@ -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
- * #=> #<TracePoint:disabled>
- *
- * 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<argc; i++) {
- events |= symbol2event_flag(argv[i]);
- }
+ for (i=0; i<argc; i++) {
+ events |= symbol2event_flag(RARRAY_AREF(args, i));
+ }
}
else {
events = RUBY_EVENT_TRACEPOINT_ALL;
@@ -1592,23 +1428,15 @@ tracepoint_new_s(int argc, VALUE *argv, VALUE self)
}
static VALUE
-tracepoint_trace_s(int argc, VALUE *argv, VALUE self)
+tracepoint_trace_s(rb_execution_context_t *ec, VALUE self, VALUE args)
{
- VALUE trace = tracepoint_new_s(argc, argv, self);
+ VALUE trace = tracepoint_new_s(ec, self, args);
rb_tracepoint_enable(trace);
return trace;
}
-/*
- * call-seq:
- * trace.inspect -> 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
- * #=> #<TracePoint:disabled>
- *
- * trace.enable
- * #=> false
- *
- * 0 / 0
- * #=> [5, :raise, #<ZeroDivisionError: divided by 0>]
- *
- * == 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] }
- * #=> #<TracePoint:enabled>
- *
- * 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 {