summaryrefslogtreecommitdiff
path: root/vm_core.h
diff options
context:
space:
mode:
Diffstat (limited to 'vm_core.h')
-rw-r--r--vm_core.h51
1 files changed, 32 insertions, 19 deletions
diff --git a/vm_core.h b/vm_core.h
index d578b5c6e5..b22a1fb023 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -474,7 +474,7 @@ struct rb_iseq_constant_body {
/* typedef rb_iseq_t is in method.h */
struct rb_iseq_struct {
VALUE flags;
- VALUE reserved1;
+ struct rb_hook_list_struct *local_hooks;
struct rb_iseq_constant_body *body;
union { /* 4, 5 words */
@@ -485,7 +485,7 @@ struct rb_iseq_struct {
int index;
} loader;
- rb_event_flag_t trace_events;
+ rb_event_flag_t global_trace_events;
} aux;
};
@@ -577,7 +577,8 @@ void rb_objspace_free(struct rb_objspace *);
typedef struct rb_hook_list_struct {
struct rb_event_hook_struct *hooks;
rb_event_flag_t events;
- int need_clean;
+ unsigned int need_clean;
+ unsigned int running;
} rb_hook_list_t;
typedef struct rb_vm_struct {
@@ -608,8 +609,6 @@ typedef struct rb_vm_struct {
unsigned int thread_report_on_exception: 1;
unsigned int safe_level_: 1;
-
- int trace_running;
int sleeper;
/* object management */
@@ -634,7 +633,7 @@ typedef struct rb_vm_struct {
} trap_list;
/* hook */
- rb_hook_list_t event_hooks;
+ rb_hook_list_t global_hooks;
/* relation table of ensure - rollback for callcc */
struct st_table *ensure_rollback_table;
@@ -1694,7 +1693,8 @@ RUBY_SYMBOL_EXPORT_BEGIN
RUBY_EXTERN rb_vm_t *ruby_current_vm_ptr;
RUBY_EXTERN rb_execution_context_t *ruby_current_execution_context_ptr;
RUBY_EXTERN rb_event_flag_t ruby_vm_event_flags;
-RUBY_EXTERN rb_event_flag_t ruby_vm_event_enabled_flags;
+RUBY_EXTERN rb_event_flag_t ruby_vm_event_enabled_global_flags;
+RUBY_EXTERN unsigned int ruby_vm_event_local_num;
RUBY_SYMBOL_EXPORT_END
@@ -1805,6 +1805,7 @@ rb_vm_check_ints(rb_execution_context_t *ec)
}
/* tracer */
+
struct rb_trace_arg_struct {
rb_event_flag_t event;
rb_execution_context_t *ec;
@@ -1822,24 +1823,29 @@ struct rb_trace_arg_struct {
VALUE path;
};
-void rb_exec_event_hooks(struct rb_trace_arg_struct *trace_arg, int pop_p);
+void rb_hook_list_mark(rb_hook_list_t *hooks);
+void rb_hook_list_free(rb_hook_list_t *hooks);
+void rb_hook_list_connect_tracepoint(VALUE target, rb_hook_list_t *list, VALUE tpval);
+void rb_hook_list_remove_tracepoint(rb_hook_list_t *list, VALUE tpval);
-#define EXEC_EVENT_HOOK_ORIG(ec_, flag_, vm_flags_, self_, id_, called_id_, klass_, data_, pop_p_) do { \
+void rb_exec_event_hooks(struct rb_trace_arg_struct *trace_arg, rb_hook_list_t *hooks, int pop_p);
+
+#define EXEC_EVENT_HOOK_ORIG(ec_, hooks_, flag_, self_, id_, called_id_, klass_, data_, pop_p_) do { \
const rb_event_flag_t flag_arg_ = (flag_); \
- if (UNLIKELY(vm_flags_ & (flag_arg_))) { \
- /* defer evaluating the other arguments */ \
- rb_exec_event_hook_orig(ec_, flag_arg_, self_, id_, called_id_, klass_, data_, pop_p_); \
+ rb_hook_list_t *hooks_arg_ = (hooks_); \
+ if (UNLIKELY((hooks_arg_)->events & (flag_arg_))) { \
+ /* defer evaluating the other arguments */ \
+ rb_exec_event_hook_orig(ec_, hooks_arg_, flag_arg_, self_, id_, called_id_, klass_, data_, pop_p_); \
} \
} while (0)
static inline void
-rb_exec_event_hook_orig(rb_execution_context_t *ec, const rb_event_flag_t flag,
- VALUE self, ID id, ID called_id, VALUE klass, VALUE data, int pop_p)
+rb_exec_event_hook_orig(rb_execution_context_t *ec, rb_hook_list_t *hooks, rb_event_flag_t flag,
+ VALUE self, ID id, ID called_id, VALUE klass, VALUE data, int pop_p)
{
struct rb_trace_arg_struct trace_arg;
- VM_ASSERT(rb_ec_vm_ptr(ec)->event_hooks.events == ruby_vm_event_flags);
- VM_ASSERT(rb_ec_vm_ptr(ec)->event_hooks.events & flag);
+ VM_ASSERT((hooks->events & flag) != 0);
trace_arg.event = flag;
trace_arg.ec = ec;
@@ -1851,14 +1857,21 @@ rb_exec_event_hook_orig(rb_execution_context_t *ec, const rb_event_flag_t flag,
trace_arg.data = data;
trace_arg.path = Qundef;
trace_arg.klass_solved = 0;
- rb_exec_event_hooks(&trace_arg, pop_p);
+
+ rb_exec_event_hooks(&trace_arg, hooks, pop_p);
+}
+
+static inline rb_hook_list_t *
+rb_vm_global_hooks(const rb_execution_context_t *ec)
+{
+ return &rb_ec_vm_ptr(ec)->global_hooks;
}
#define EXEC_EVENT_HOOK(ec_, flag_, self_, id_, called_id_, klass_, data_) \
- EXEC_EVENT_HOOK_ORIG(ec_, flag_, ruby_vm_event_flags, self_, id_, called_id_, klass_, data_, 0)
+ EXEC_EVENT_HOOK_ORIG(ec_, rb_vm_global_hooks(ec_), flag_, self_, id_, called_id_, klass_, data_, 0)
#define EXEC_EVENT_HOOK_AND_POP_FRAME(ec_, flag_, self_, id_, called_id_, klass_, data_) \
- EXEC_EVENT_HOOK_ORIG(ec_, flag_, ruby_vm_event_flags, self_, id_, called_id_, klass_, data_, 1)
+ EXEC_EVENT_HOOK_ORIG(ec_, rb_vm_global_hooks(ec_), flag_, self_, id_, called_id_, klass_, data_, 1)
RUBY_SYMBOL_EXPORT_BEGIN