Skip to content

Commit a0ab169

Browse files
committed
Merge pull request #21 from denofevil/disabling-enabling-tps
Disabling enabling trace points to improve performance
2 parents d675966 + 247cf89 commit a0ab169

File tree

6 files changed

+117
-23
lines changed

6 files changed

+117
-23
lines changed

ext/context.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ context_create(VALUE thread, VALUE cDebugThread) {
147147
context->last_line = -1;
148148
context->stop_frame = -1;
149149
context->thread_pause = 0;
150+
context->stop_reason = CTX_STOP_NONE;
150151
reset_stepping_stop_points(context);
151152
if(rb_obj_class(thread) == cDebugThread) CTX_FL_SET(context, CTX_FL_IGNORE);
152153
return Data_Wrap_Struct(cContext, Context_mark, Context_free, context);
@@ -272,6 +273,7 @@ Context_pause(VALUE self)
272273
return Qfalse;
273274
}
274275

276+
enable_trace_points();
275277
context->thread_pause = 1;
276278
return Qtrue;
277279
}

ext/debase_internals.c

Lines changed: 103 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ static VALUE idAtCatchpoint;
2323
static VALUE idFileFilter;
2424
static VALUE idAccept;
2525

26+
static void
27+
print_debug(const char *message, ...)
28+
{
29+
va_list ap;
30+
31+
if (verbose == Qfalse) return;
32+
va_start(ap, message);
33+
vfprintf(stderr, message, ap);
34+
va_end(ap);
35+
}
36+
2637
static VALUE
2738
is_path_accepted(VALUE path) {
2839
VALUE filter;
@@ -49,6 +60,82 @@ Debase_current_context(VALUE self)
4960
return Debase_thread_context(self, rb_thread_current());
5061
}
5162

63+
static int
64+
set_recalc_flag(VALUE thread, VALUE context_object, VALUE ignored)
65+
{
66+
debug_context_t *context;
67+
68+
Data_Get_Struct(context_object, debug_context_t, context);
69+
CTX_FL_SET(context, CTX_FL_UPDATE_STACK);
70+
71+
return ST_CONTINUE;
72+
}
73+
74+
static int
75+
can_disable_trace_points(VALUE thread, VALUE context_object, VALUE result)
76+
{
77+
debug_context_t *context;
78+
79+
Data_Get_Struct(context_object, debug_context_t, context);
80+
81+
if (-1 != context->dest_frame
82+
|| context->stop_line >= 0
83+
|| -1 != context->stop_next
84+
|| context->stop_reason != CTX_STOP_NONE
85+
|| context->thread_pause != 0)
86+
{
87+
print_debug("can_disable_tp: %d %d %d %d\n", context->dest_frame, context->stop_line,
88+
context->stop_next, context->stop_reason);
89+
*((VALUE *) result) = Qfalse;
90+
return ST_STOP;
91+
}
92+
return ST_CONTINUE;
93+
}
94+
95+
static void
96+
try_disable_trace_points()
97+
{
98+
VALUE can_disable = Qtrue;
99+
100+
if (RARRAY_LEN(breakpoints) != 0) return;
101+
print_debug("disable_tps: no breakpoints\n");
102+
if (RHASH_EMPTY_P(catchpoints)) return;
103+
print_debug("disable_tps: no catchpoints\n");
104+
if (rb_tracepoint_enabled_p(tpLine) == Qfalse) return;
105+
print_debug("disable_tps: tps are enabled\n");
106+
107+
rb_hash_foreach(contexts, can_disable_trace_points, (VALUE)&can_disable);
108+
if (can_disable == Qfalse) return;
109+
print_debug("disable_tps: can disable contexts\n");
110+
111+
rb_tracepoint_disable(tpLine);
112+
rb_tracepoint_disable(tpCall);
113+
rb_tracepoint_disable(tpReturn);
114+
rb_tracepoint_disable(tpRaise);
115+
rb_hash_foreach(contexts, set_recalc_flag, 0);
116+
}
117+
118+
extern VALUE
119+
enable_trace_points()
120+
{
121+
print_debug("enable_tps: \n");
122+
if (rb_tracepoint_enabled_p(tpLine) == Qtrue) return Qtrue;
123+
print_debug("enable_tps: need to enable\n");
124+
125+
rb_tracepoint_enable(tpLine);
126+
rb_tracepoint_enable(tpCall);
127+
rb_tracepoint_enable(tpReturn);
128+
rb_tracepoint_enable(tpRaise);
129+
130+
return Qfalse;
131+
}
132+
133+
static VALUE
134+
Debase_enable_trace_points(VALUE self)
135+
{
136+
return enable_trace_points();
137+
}
138+
52139
static int
53140
remove_dead_threads(VALUE thread, VALUE context, VALUE ignored)
54141
{
@@ -71,6 +158,8 @@ cleanup(debug_context_t *context)
71158
thread = remove_from_locked();
72159
if(thread != Qnil)
73160
rb_thread_run(thread);
161+
162+
try_disable_trace_points();
74163
}
75164

76165
static int
@@ -377,15 +466,18 @@ Debase_setup_tracepoints(VALUE self)
377466
catchpoints = rb_hash_new();
378467

379468
tpLine = rb_tracepoint_new(Qnil, RUBY_EVENT_LINE, process_line_event, NULL);
380-
rb_tracepoint_enable(tpLine);
381-
tpReturn = rb_tracepoint_new(Qnil, RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN | RUBY_EVENT_C_RETURN | RUBY_EVENT_END,
469+
rb_global_variable(&tpLine);
470+
471+
tpReturn = rb_tracepoint_new(Qnil, RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN | RUBY_EVENT_C_RETURN | RUBY_EVENT_END,
382472
process_return_event, NULL);
383-
rb_tracepoint_enable(tpReturn);
384-
tpCall = rb_tracepoint_new(Qnil, RUBY_EVENT_CALL | RUBY_EVENT_B_CALL | RUBY_EVENT_C_CALL | RUBY_EVENT_CLASS,
473+
rb_global_variable(&tpReturn);
474+
475+
tpCall = rb_tracepoint_new(Qnil, RUBY_EVENT_CALL | RUBY_EVENT_B_CALL | RUBY_EVENT_C_CALL | RUBY_EVENT_CLASS,
385476
process_call_event, NULL);
386-
rb_tracepoint_enable(tpCall);
477+
rb_global_variable(&tpCall);
478+
387479
tpRaise = rb_tracepoint_new(Qnil, RUBY_EVENT_RAISE, process_raise_event, NULL);
388-
Debase_current_context(self);
480+
rb_global_variable(&tpRaise);
389481

390482
return Qnil;
391483
}
@@ -418,7 +510,10 @@ debase_prepare_context(VALUE self, VALUE file, VALUE stop)
418510
context_object = Debase_current_context(self);
419511
Data_Get_Struct(context_object, debug_context_t, context);
420512

421-
if(RTEST(stop)) context->stop_next = 1;
513+
if(RTEST(stop)) {
514+
context->stop_next = 1;
515+
Debase_enable_trace_points(self);
516+
}
422517
ruby_script(RSTRING_PTR(file));
423518
return self;
424519
}
@@ -510,18 +605,6 @@ Debase_set_verbose(VALUE self, VALUE value)
510605
return value;
511606
}
512607

513-
/*
514-
* call-seq:
515-
* Debase.tp_raise -> TracePoint
516-
*
517-
* Returns trace point we use to track :raise events
518-
*/
519-
static VALUE
520-
Debase_get_tp_raise(VALUE self)
521-
{
522-
return tpRaise;
523-
}
524-
525608
/*
526609
* Document-class: Debase
527610
*
@@ -541,10 +624,10 @@ Init_debase_internals()
541624
rb_define_module_function(mDebase, "contexts", Debase_contexts, 0);
542625
rb_define_module_function(mDebase, "breakpoints", Debase_breakpoints, 0);
543626
rb_define_module_function(mDebase, "catchpoints", Debase_catchpoints, 0);
544-
rb_define_module_function(mDebase, "tp_raise", Debase_get_tp_raise, 0);
545627
rb_define_module_function(mDebase, "started?", Debase_started, 0);
546628
rb_define_module_function(mDebase, "verbose?", Debase_verbose, 0);
547629
rb_define_module_function(mDebase, "verbose=", Debase_set_verbose, 1);
630+
rb_define_module_function(mDebase, "enable_trace_points", Debase_enable_trace_points, 0);
548631

549632
idAlive = rb_intern("alive?");
550633
idAtLine = rb_intern("at_line");

ext/debase_internals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ typedef struct rb_trace_arg_struct rb_trace_point_t;
1818
#define CTX_FL_STEPPED (1<<8)
1919
#define CTX_FL_FORCE_MOVE (1<<9)
2020
#define CTX_FL_CATCHING (1<<10)
21+
#define CTX_FL_UPDATE_STACK (1<<11)
2122

2223
/* macro functions */
2324
#define CTX_FL_TEST(c,f) ((c)->flags & (f))
@@ -88,6 +89,7 @@ typedef struct locked_thread_t {
8889
extern int is_in_locked(VALUE thread_id);
8990
extern void add_to_locked(VALUE thread);
9091
extern VALUE remove_from_locked();
92+
extern VALUE enable_trace_points();
9193

9294
/* breakpoints and catchpoints */
9395
/* types */

ext/hacks.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,8 @@ update_stack_size(debug_context_t *context)
1010
thread = ruby_current_thread;
1111
/* see backtrace_each in vm_backtrace.c */
1212
context->stack_size = (int)(RUBY_VM_END_CONTROL_FRAME(thread) - thread->cfp - 1);
13+
if (CTX_FL_TEST(context, CTX_FL_UPDATE_STACK)) {
14+
context->calced_stack_size = context->stack_size;
15+
CTX_FL_UNSET(context, CTX_FL_UPDATE_STACK);
16+
}
1317
}

lib/debase.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def start(options={}, &block)
2929
def add_breakpoint(file, line, expr=nil)
3030
breakpoint = Breakpoint.new(file, line, expr)
3131
breakpoints << breakpoint
32+
enable_trace_points
3233
breakpoint
3334
end
3435

@@ -48,17 +49,15 @@ def debug
4849

4950
def add_catchpoint(exception)
5051
catchpoints[exception] = 0
51-
tp_raise.enable
52+
enable_trace_points
5253
end
5354

5455
def remove_catchpoint(exception)
5556
catchpoints.delete(exception)
56-
tp_raise.disable if catchpoints.empty?
5757
end
5858

5959
def clear_catchpoints
6060
catchpoints.clear
61-
tp_raise.disable
6261
end
6362

6463
#call-seq:

test/test_base.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ def test_current_context
1212
assert_equal(false, Debugger.started?,
1313
'debugger should not initially be started.')
1414
Debugger.start_
15+
# we need to add the breakpoint to force enabling trace points
16+
Debugger.add_breakpoint(__FILE__, 1)
1517
assert(Debugger.started?,
1618
'debugger should now be started.')
1719
# assert_equal(__LINE__, Debugger.current_context.frame_line)
@@ -37,6 +39,8 @@ def test_debugger_base
3739
assert_equal(false, Debugger.started?,
3840
'Debugger should not initially be started.')
3941
Debugger.start_
42+
# we need to add the breakpoint to force enabling trace points
43+
Debugger.add_breakpoint(__FILE__, 1)
4044
assert(Debugger.started?,
4145
'Debugger should now be started.')
4246
assert_equal(false, Debugger.debug,

0 commit comments

Comments
 (0)