perftools.rb 0.1.8 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -114,11 +114,11 @@ google-perftools for ruby code
114
114
 
115
115
  To profile C code, download and build an unpatched perftools (libunwind or ./configure --enable-frame-pointers required on x86_64):
116
116
 
117
- wget http://google-perftools.googlecode.com/files/google-perftools-1.2.tar.gz
118
- tar zxvf google-perftools-1.2.tar.gz
119
- cd google-perftools-1.2
117
+ wget http://google-perftools.googlecode.com/files/google-perftools-1.3.tar.gz
118
+ tar zxvf google-perftools-1.3.tar.gz
119
+ cd google-perftools-1.3
120
120
 
121
- ./configure --prefix=/opt --disable-shared
121
+ ./configure --prefix=/opt
122
122
  make
123
123
  sudo make install
124
124
 
data/ext/extconf.rb CHANGED
@@ -36,6 +36,7 @@ Dir.chdir('src') do
36
36
  xsystem("tar zxvf #{perftools}")
37
37
  Dir.chdir(dir) do
38
38
  xsystem("patch -p1 < ../../../patches/perftools.patch")
39
+ xsystem("patch -p1 < ../../../patches/perftools-gc.patch")
39
40
  xsystem("patch -p1 < ../../../patches/perftools-osx.patch") if RUBY_PLATFORM =~ /darwin/
40
41
  xsystem("patch -p1 < ../../../patches/perftools-debug.patch")# if ENV['DEBUG']
41
42
  end
@@ -63,4 +64,4 @@ end
63
64
 
64
65
  $libs = append_library($libs, 'rubyprofiler')
65
66
  have_func('rb_during_gc', 'ruby.h')
66
- create_makefile 'perftools'
67
+ create_makefile 'perftools'
data/ext/perftools.c CHANGED
@@ -3,6 +3,7 @@
3
3
  #include <env.h>
4
4
 
5
5
  static VALUE Iallocate;
6
+ static VALUE I__send__;
6
7
 
7
8
  static inline void
8
9
  save_frame(struct FRAME *frame, void** result, int *depth)
@@ -12,6 +13,9 @@ save_frame(struct FRAME *frame, void** result, int *depth)
12
13
  // if (BUILTIN_TYPE(klass) == T_ICLASS)
13
14
  // klass = RBASIC(klass)->klass;
14
15
 
16
+ if (frame->last_func == I__send__)
17
+ return;
18
+
15
19
  if (FL_TEST(klass, FL_SINGLETON) &&
16
20
  (BUILTIN_TYPE(frame->self) == T_CLASS || BUILTIN_TYPE(frame->self) == T_MODULE))
17
21
  result[(*depth)++] = (void*) frame->self;
@@ -42,6 +46,8 @@ rb_stack_trace(void** result, int max_depth)
42
46
  }
43
47
  #endif
44
48
 
49
+ // XXX SIGPROF can come in while ruby_frame is in an inconsistent state (rb_call0), so we ignore the top-most frame
50
+ /*
45
51
  // XXX does it make sense to track allocations or not?
46
52
  if (frame->last_func == ID_ALLOCATOR) {
47
53
  frame = frame->prev;
@@ -50,6 +56,7 @@ rb_stack_trace(void** result, int max_depth)
50
56
  if (frame->last_func) {
51
57
  save_frame(frame, result, &depth);
52
58
  }
59
+ */
53
60
 
54
61
  for (; frame && (n = frame->node); frame = frame->prev) {
55
62
  if (frame->prev && frame->prev->last_func) {
@@ -70,6 +77,7 @@ rb_stack_trace(void** result, int max_depth)
70
77
  static VALUE cPerfTools;
71
78
  static VALUE cCpuProfiler;
72
79
  static VALUE bProfilerRunning;
80
+ static VALUE gc_hook;
73
81
 
74
82
  VALUE
75
83
  cpuprofiler_running_p(VALUE self)
@@ -108,6 +116,12 @@ cpuprofiler_start(VALUE self, VALUE filename)
108
116
  return Qtrue;
109
117
  }
110
118
 
119
+ static void
120
+ cpuprofiler_gc_mark()
121
+ {
122
+ ProfilerGcMark(rb_gc_mark);
123
+ }
124
+
111
125
  void
112
126
  Init_perftools()
113
127
  {
@@ -115,8 +129,12 @@ Init_perftools()
115
129
  cCpuProfiler = rb_define_class_under(cPerfTools, "CpuProfiler", rb_cObject);
116
130
  bProfilerRunning = Qfalse;
117
131
  Iallocate = rb_intern("allocate");
132
+ I__send__ = rb_intern("__send__");
118
133
 
119
134
  rb_define_singleton_method(cCpuProfiler, "running?", cpuprofiler_running_p, 0);
120
135
  rb_define_singleton_method(cCpuProfiler, "start", cpuprofiler_start, 1);
121
136
  rb_define_singleton_method(cCpuProfiler, "stop", cpuprofiler_stop, 0);
122
- }
137
+
138
+ gc_hook = Data_Wrap_Struct(cCpuProfiler, cpuprofiler_gc_mark, NULL, NULL);
139
+ rb_global_variable(&gc_hook);
140
+ }
@@ -0,0 +1,107 @@
1
+ diff --git a/src/profiledata.cc b/src/profiledata.cc
2
+ index e6240d9..b901ee8 100644
3
+ --- a/src/profiledata.cc
4
+ +++ b/src/profiledata.cc
5
+ @@ -198,6 +198,29 @@ static void DumpProcSelfMaps(int fd) {
6
+ }
7
+ }
8
+
9
+ +#ifdef BUILD_FOR_RUBY
10
+ +void ProfileData::GcMark(void (*mark)(VALUE)) {
11
+ + if (!enabled()) {
12
+ + return;
13
+ + }
14
+ +
15
+ + for (int b = 0; b < kBuckets; b++) {
16
+ + Bucket* bucket = &hash_[b];
17
+ + for (int a = 0; a < kAssociativity; a++) {
18
+ + if (bucket->entry[a].count > 0) {
19
+ + Entry e = bucket->entry[a];
20
+ + if (e.depth > 1)
21
+ + for (int n=0; n<e.depth; n+=3) {
22
+ + if (e.stack[n])
23
+ + mark(e.stack[n]);
24
+ + mark(e.stack[n+1]);
25
+ + }
26
+ + }
27
+ + }
28
+ + }
29
+ +}
30
+ +#endif
31
+ +
32
+ void ProfileData::Stop() {
33
+ if (!enabled()) {
34
+ return;
35
+ diff --git a/src/profiledata.h b/src/profiledata.h
36
+ index 67c463d..1df79c2 100644
37
+ --- a/src/profiledata.h
38
+ +++ b/src/profiledata.h
39
+ @@ -40,6 +40,12 @@
40
+ #ifndef BASE_PROFILEDATA_H_
41
+ #define BASE_PROFILEDATA_H_
42
+
43
+ +#ifdef BUILD_FOR_RUBY
44
+ +extern "C" {
45
+ + typedef unsigned long VALUE;
46
+ +}
47
+ +#endif
48
+ +
49
+ #include <config.h>
50
+ #include <time.h> // for time_t
51
+ #include <stdint.h>
52
+ @@ -141,6 +147,10 @@ class ProfileData {
53
+ // Get the current state of the data collector.
54
+ void GetCurrentState(State* state) const;
55
+
56
+ +#ifdef BUILD_FOR_RUBY
57
+ + void GcMark(void (*cb)(VALUE));
58
+ +#endif
59
+ +
60
+ private:
61
+ static const int kAssociativity = 4; // For hashtable
62
+ static const int kBuckets = 1 << 10; // For hashtable
63
+ diff --git a/src/profiler.cc b/src/profiler.cc
64
+ index 21c7669..b7277c7 100644
65
+ --- a/src/profiler.cc
66
+ +++ b/src/profiler.cc
67
+ @@ -87,6 +87,10 @@ class CpuProfiler {
68
+ // Write the data to disk (and continue profiling).
69
+ void FlushTable();
70
+
71
+ +#ifdef BUILD_FOR_RUBY
72
+ + void GcMark(void (*cb)(VALUE));
73
+ +#endif
74
+ +
75
+ bool Enabled();
76
+
77
+ void GetCurrentState(ProfilerState* state);
78
+ @@ -221,6 +225,16 @@ void CpuProfiler::FlushTable() {
79
+ EnableHandler();
80
+ }
81
+
82
+ +#ifdef BUILD_FOR_RUBY
83
+ +void CpuProfiler::GcMark(void (*cb)(VALUE)) {
84
+ + if (!collector_.enabled()) {
85
+ + return;
86
+ + }
87
+ +
88
+ + collector_.GcMark(cb);
89
+ +}
90
+ +#endif
91
+ +
92
+ bool CpuProfiler::Enabled() {
93
+ SpinLockHolder cl(&lock_);
94
+ return collector_.enabled();
95
+ @@ -300,6 +314,12 @@ extern "C" void ProfilerFlush() {
96
+ CpuProfiler::instance_.FlushTable();
97
+ }
98
+
99
+ +#ifdef BUILD_FOR_RUBY
100
+ +extern "C" void ProfilerGcMark(void (*cb)(VALUE)) {
101
+ + CpuProfiler::instance_.GcMark(cb);
102
+ +}
103
+ +#endif
104
+ +
105
+ extern "C" int ProfilingIsEnabledForAllThreads() {
106
+ return CpuProfiler::instance_.Enabled();
107
+ }
data/perftools.rb.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'perftools.rb'
3
- s.version = '0.1.8'
4
- s.date = '2009-06-15'
3
+ s.version = '0.2.5'
4
+ s.date = '2009-09-16'
5
5
  s.rubyforge_project = 'perftools-rb'
6
6
  s.summary = 'google-perftools for ruby code'
7
7
  s.description = 'A sampling profiler for ruby code based on patches to google-perftools'
@@ -23,6 +23,7 @@ spec = Gem::Specification.new do |s|
23
23
  "ext/extconf.rb",
24
24
  "ext/perftools.c",
25
25
  "patches/perftools-debug.patch",
26
+ "patches/perftools-gc.patch",
26
27
  "patches/perftools-osx.patch",
27
28
  "patches/perftools.patch",
28
29
  "perftools.rb.gemspec"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perftools.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aman Gupta
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-15 00:00:00 -07:00
12
+ date: 2009-09-16 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -27,6 +27,7 @@ files:
27
27
  - ext/extconf.rb
28
28
  - ext/perftools.c
29
29
  - patches/perftools-debug.patch
30
+ - patches/perftools-gc.patch
30
31
  - patches/perftools-osx.patch
31
32
  - patches/perftools.patch
32
33
  - perftools.rb.gemspec