[#27380] [Bug #2553] Fix pthreads slowness by eliminating unnecessary sigprocmask calls — Dan Peterson <redmine@...>

Bug #2553: Fix pthreads slowness by eliminating unnecessary sigprocmask calls

21 messages 2010/01/03

[#27437] [Feature #2561] 1.8.7 Patch reduces time cost of Rational operations by 50%. — Kurt Stephens <redmine@...>

Feature #2561: 1.8.7 Patch reduces time cost of Rational operations by 50%.

9 messages 2010/01/06

[#27447] [Bug #2564] [patch] re-initialize timer_thread_{lock,cond} after fork — Aliaksey Kandratsenka <redmine@...>

Bug #2564: [patch] re-initialize timer_thread_{lock,cond} after fork

18 messages 2010/01/06

[#27545] [Feature #2594] 1.8.7 Patch: Reduce time spent in gc.c is_pointer_to_heap(). — Kurt Stephens <redmine@...>

Feature #2594: 1.8.7 Patch: Reduce time spent in gc.c is_pointer_to_heap().

8 messages 2010/01/11

[#27635] [Bug #2619] Proposed method: Process.fork_supported? — Hongli Lai <redmine@...>

Bug #2619: Proposed method: Process.fork_supported?

45 messages 2010/01/20
[#27643] [Feature #2619] Proposed method: Process.fork_supported? — Luis Lavena <redmine@...> 2010/01/21

Issue #2619 has been updated by Luis Lavena.

[#27678] Re: [Feature #2619] Proposed method: Process.fork_supported? — Yukihiro Matsumoto <matz@...> 2010/01/22

Hi,

[#27684] Re: [Feature #2619] Proposed method: Process.fork_supported? — Charles Oliver Nutter <headius@...> 2010/01/22

On Thu, Jan 21, 2010 at 11:27 PM, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

[#27708] Re: [Feature #2619] Proposed method: Process.fork_supported? — Yukihiro Matsumoto <matz@...> 2010/01/22

Hi,

[#27646] Re: [Bug #2619] Proposed method: Process.fork_supported? — Tanaka Akira <akr@...> 2010/01/21

2010/1/21 Hongli Lai <redmine@ruby-lang.org>:

[#27652] Re: [Bug #2619] Proposed method: Process.fork_supported? — Hongli Lai <hongli@...99.net> 2010/01/21

On 1/21/10 5:20 AM, Tanaka Akira wrote:

[#27653] Re: [Bug #2619] Proposed method: Process.fork_supported? — Tanaka Akira <akr@...> 2010/01/21

2010/1/21 Hongli Lai <hongli@plan99.net>:

[#27662] Re: [Bug #2619] Proposed method: Process.fork_supported? — Vladimir Sizikov <vsizikov@...> 2010/01/21

On Thu, Jan 21, 2010 at 10:53 AM, Tanaka Akira <akr@fsij.org> wrote:

[#27698] [Bug #2629] ConditionVariable#wait(mutex, timeout) should return whether the condition was signalled, not the waited time — Hongli Lai <redmine@...>

Bug #2629: ConditionVariable#wait(mutex, timeout) should return whether the condition was signalled, not the waited time

8 messages 2010/01/22

[#27722] [Feature #2635] Unbundle rdoc — Yui NARUSE <redmine@...>

Feature #2635: Unbundle rdoc

14 messages 2010/01/23

[#27757] [Bug #2638] ruby-1.9.1-p37[68] build on aix5.3 with gcc-4.2 failed to run for me because it ignores where libgcc is located. — Joel Soete <redmine@...>

Bug #2638: ruby-1.9.1-p37[68] build on aix5.3 with gcc-4.2 failed to run for me because it ignores where libgcc is located.

10 messages 2010/01/24

[#27778] [Bug #2641] Seg fault running miniruby during ruby build on Haiku — Alexander von Gluck <redmine@...>

Bug #2641: Seg fault running miniruby during ruby build on Haiku

10 messages 2010/01/25

[#27791] [Bug #2644] memory over-allocation with regexp — Greg Hazel <redmine@...>

Bug #2644: memory over-allocation with regexp

12 messages 2010/01/25

[#27794] [Bug #2647] Lack of testing for String#split — Hugh Sasse <redmine@...>

Bug #2647: Lack of testing for String#split

14 messages 2010/01/25

[#27912] [Bug #2669] mkmf find_executable doesn't find .bat files — Roger Pack <redmine@...>

Bug #2669: mkmf find_executable doesn't find .bat files

11 messages 2010/01/27

[#27930] [Bug:trunk] some behavior changes of lib/csv.rb between 1.8 and 1.9 — Yusuke ENDOH <mame@...>

Hi jeg2, or anyone who knows the implementation of FasterCSV,

15 messages 2010/01/28
[#27931] Re: [Bug:trunk] some behavior changes of lib/csv.rb between 1.8 and 1.9 — James Edward Gray II <james@...> 2010/01/28

On Jan 28, 2010, at 10:51 AM, Yusuke ENDOH wrote:

[ruby-core:27448] [Feature:trunk] adding hooks for better tracing

From: Yugui <yugui@...>
Date: 2010-01-06 14:15:18 UTC
List: ruby-core #27448
Hi,

I made a commit that embeded dtrace probes into Ruby so that you can
profile a Ruby application at runtime. (r26235)

Adding probes had been approved by a Ruby developer's meeting,
however, the commit was little larger than what other committers
expected. I got some objection for the commit. [ruby-dev:39954]
In the end, I decided to temporarily revert the commit. (r26243)

I discussed how we should support dynamic runtime tracing, with ko1,
mame, naruse, unak and shyouhei. The problems of the commit were:
* the probes duplicated with the event_hook framework
(rb_add_event_hook, Kernel#set_trace_func)
* Design of the probes were not verified enough.
  * more trial and error are necessary, to make it clear what is
necessary to trace a Ruby application.

I accepted ko1's suggestion:
* reverting the commit
* adding some hooks for rb_add_event_hook().
* implementing probes for dynamic runtime tracing on the event_hook framework.
  * these probes can be implemented as a gem
  * I will aget a chance for trial and error.
  * The probes possibly will be merged into Ruby itself after enough
designed and getting enough use cases.

Here is a patch to add the hooks I and ko1 talked about. (attached)
And here is an extension library that provides prove points to dtrace,
on top of the hooks. (http://github.com/yugui/vm_probes )

What do you think?  Can I commit the patch I attached?

Thank you,
-- Yuki Sonoda (Yugui)

Attachments (1)

adding-hooks.patch (4.75 KB, text/x-diff)
diff --git a/compile.c b/compile.c
index 54b513c..ea4268a 100644
--- a/compile.c
+++ b/compile.c
@@ -3569,6 +3569,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 	    }
 	    ADD_INSNL(ret, nd_line(node), jump, label_miss);
 	    ADD_LABEL(ret, label_hit);
+	    ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RESCUE);
 	    COMPILE(ret, "resbody body", resq->nd_body);
 	    if (iseq->compile_data->option->tailcall_optimization) {
 		ADD_INSN(ret, nd_line(node), nop);
diff --git a/gc.c b/gc.c
index 4021220..35489aa 100644
--- a/gc.c
+++ b/gc.c
@@ -1059,17 +1059,17 @@ rb_during_gc(void)
 VALUE
 rb_newobj(void)
 {
-#if USE_VALUE_CACHE || (defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE)
     rb_thread_t *th = GET_THREAD();
-#endif
-#if USE_VALUE_CACHE
-    VALUE v = *th->value_cache_ptr;
-#endif
 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
     rb_objspace_t *objspace = th->vm->objspace;
 #else
     rb_objspace_t *objspace = &rb_objspace;
 #endif
+#if USE_VALUE_CACHE
+    VALUE v = *th->value_cache_ptr;
+#else
+    VALUE v = rb_newobj_from_heap(objspace);
+#endif
 
     if (during_gc) {
 	dont_gc = 1;
@@ -1085,15 +1085,14 @@ rb_newobj(void)
     else {
 	v = rb_fill_value_cache(th);
     }
+#endif
 
 #if defined(GC_DEBUG)
     printf("cache index: %d, v: %p, th: %p\n",
 	   th->value_cache_ptr - th->value_cache, v, th);
 #endif
+    EXEC_EVENT_HOOK(th, RUBY_EVENT_OBJ_ALLOC, v, 0, 0);
     return v;
-#else
-    return rb_newobj_from_heap(objspace);
-#endif
 }
 
 NODE*
@@ -1973,6 +1972,8 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
 	break;
     }
 
+    EXEC_EVENT_HOOK(GET_THREAD(), RUBY_EVENT_OBJ_FREE, obj, 0, 0);
+
     if (FL_TEST(obj, FL_EXIVAR)) {
 	rb_free_generic_ivar((VALUE)obj);
 	FL_UNSET(obj, FL_EXIVAR);
@@ -2153,6 +2154,7 @@ garbage_collect(rb_objspace_t *objspace)
     during_gc++;
     objspace->count++;
 
+    EXEC_EVENT_HOOK(th, RUBY_EVENT_GC_START, 0, 0, 0);
     GC_PROF_TIMER_START;
     GC_PROF_MARK_TIMER_START;
     SET_STACK_END;
@@ -2201,6 +2203,7 @@ garbage_collect(rb_objspace_t *objspace)
     GC_PROF_SWEEP_TIMER_STOP;
 
     GC_PROF_TIMER_STOP;
+    EXEC_EVENT_HOOK(th, RUBY_EVENT_GC_END, 0, 0, 0);
     if (GC_NOTIFY) printf("end garbage_collect()\n");
     return TRUE;
 }
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index 5318772..7b8c982 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -1316,19 +1316,26 @@ void ruby_sysinit(int *, char ***);
 #define HAVE_NATIVETHREAD
 int ruby_native_thread_p(void);
 
-#define RUBY_EVENT_NONE      0x0000
-#define RUBY_EVENT_LINE      0x0001
-#define RUBY_EVENT_CLASS     0x0002
-#define RUBY_EVENT_END       0x0004
-#define RUBY_EVENT_CALL      0x0008
-#define RUBY_EVENT_RETURN    0x0010
-#define RUBY_EVENT_C_CALL    0x0020
-#define RUBY_EVENT_C_RETURN  0x0040
-#define RUBY_EVENT_RAISE     0x0080
-#define RUBY_EVENT_ALL       0xffff
-#define RUBY_EVENT_VM       0x10000
-#define RUBY_EVENT_SWITCH   0x20000
-#define RUBY_EVENT_COVERAGE 0x40000
+#define RUBY_EVENT_NONE        0x0000
+#define RUBY_EVENT_LINE        0x0001
+#define RUBY_EVENT_CLASS       0x0002
+#define RUBY_EVENT_END         0x0004
+#define RUBY_EVENT_CALL        0x0008
+#define RUBY_EVENT_RETURN      0x0010
+#define RUBY_EVENT_C_CALL      0x0020
+#define RUBY_EVENT_C_RETURN    0x0040
+#define RUBY_EVENT_RAISE       0x0080
+#define RUBY_EVENT_ALL         0xffff
+#define RUBY_EVENT_VM         0x10000
+#define RUBY_EVENT_SWITCH     0x20000
+#define RUBY_EVENT_COVERAGE   0x40000
+#define RUBY_EVENT_TH_INIT    0x80000
+#define RUBY_EVENT_TH_TERM   0x100000
+#define RUBY_EVENT_RESCUE    0x200000
+#define RUBY_EVENT_OBJ_ALLOC 0x400000
+#define RUBY_EVENT_OBJ_FREE  0x800000
+#define RUBY_EVENT_GC_START 0x1000000
+#define RUBY_EVENT_GC_END   0x2000000
 
 typedef unsigned int rb_event_flag_t;
 typedef void (*rb_event_hook_func_t)(rb_event_flag_t, VALUE data, VALUE, ID, VALUE klass);
diff --git a/thread.c b/thread.c
index 0ba41c7..06a7da4 100644
--- a/thread.c
+++ b/thread.c
@@ -376,6 +376,8 @@ thread_cleanup_func(void *th_ptr)
 {
     rb_thread_t *th = th_ptr;
 
+    EXEC_EVENT_HOOK(th, RUBY_EVENT_TH_TERM, th->self, 0, 0);
+
     /* unlock all locking mutexes */
     if (th->keeping_mutexes) {
 	rb_mutex_unlock_all(th->keeping_mutexes, th);
@@ -533,6 +535,7 @@ thread_create_core(VALUE thval, VALUE args, VALUE (*fn)(ANYARGS))
     native_mutex_initialize(&th->interrupt_lock);
     /* kick thread */
     st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id);
+    EXEC_EVENT_HOOK(GET_THREAD(), RUBY_EVENT_TH_INIT, thval, 0, 0);
     err = native_thread_create(th);
     if (err) {
 	st_delete_wrap(th->vm->living_threads, th->self);
@@ -3680,6 +3683,7 @@ thread_reset_event_flags(rb_thread_t *th)
 	flag |= hook->flag;
 	hook = hook->next;
     }
+    th->event_flags = flag;
 }
 
 static void

In This Thread

Prev Next