rblineprof 0.3.3.beta → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a6c7319f8169d091dde957717561a5776edfec3e
4
+ data.tar.gz: a39aa28cc67dbe8084b68085ec8ce495fdcf3655
5
+ SHA512:
6
+ metadata.gz: 26059d9a1c174f9fa1721bc66ae6339ac0727b0164f7f9df8f973315a64bb8e94f359db6461a50f083e7a6abb772ad113fbf8a7041d72eb13459d6efe90daf33
7
+ data.tar.gz: 56f634c3c42af0a5b040fb68c2eeb11f45561f2c6613781f8a84d86a80843dcb74ef6f97d55e7b4786923a0a19f734490c62ba61af5c62c6a9b62f020a3ba139
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ /tmp
2
+ /lib/*.bundle
3
+ /lib/*.so
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,16 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rblineprof (0.3.2)
5
+ debugger-ruby_core_source (~> 1.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ debugger-ruby_core_source (1.3.1)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ rblineprof!
data/README.md CHANGED
@@ -31,6 +31,10 @@
31
31
  | end
32
32
  ```
33
33
 
34
+ ### Rails integration
35
+
36
+ * [peek-rblineprof](https://github.com/peek/peek-rblineprof#peekrblineprof)
37
+
34
38
  ## Other profilers
35
39
 
36
40
  * [PLine](https://github.com/soba1104/PLine) line-profiler for ruby 1.9
@@ -39,3 +43,7 @@
39
43
  * [ruby-prof](https://github.com/rdp/ruby-prof)
40
44
  * [perftools.rb](https://github.com/tmm1/perftools.rb)
41
45
  * [zenprofile](https://github.com/seattlerb/zenprofile)
46
+
47
+ ## License
48
+
49
+ rblineprof is released under the [MIT License](http://www.opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ task :default => :test
2
+
3
+ # ==========================================================
4
+ # Packaging
5
+ # ==========================================================
6
+
7
+ GEMSPEC = eval(File.read('rblineprof.gemspec'))
8
+
9
+ require 'rubygems/package_task'
10
+ Gem::PackageTask.new(GEMSPEC) do |pkg|
11
+ end
12
+
13
+ # ==========================================================
14
+ # Ruby Extension
15
+ # ==========================================================
16
+
17
+ require 'rake/extensiontask'
18
+ Rake::ExtensionTask.new('rblineprof', GEMSPEC) do |ext|
19
+ ext.ext_dir = 'ext'
20
+ end
21
+ task :build => :compile
22
+
23
+ # ==========================================================
24
+ # Testing
25
+ # ==========================================================
26
+
27
+ require 'rake/testtask'
28
+ Rake::TestTask.new 'test' do |t|
29
+ t.test_files = FileList['test/test_*.rb']
30
+ end
31
+ task :test => :build
data/ext/extconf.rb CHANGED
@@ -2,7 +2,12 @@ require 'mkmf'
2
2
 
3
3
  have_func('rb_os_allocated_objects')
4
4
 
5
- if RUBY_VERSION >= "1.9"
5
+ if RUBY_VERSION >= "2.1"
6
+ have_func('rb_gc_stat')
7
+ have_func('rb_profile_frames')
8
+ have_func('rb_tracepoint_new')
9
+ create_makefile 'rblineprof'
10
+ elsif RUBY_VERSION >= "1.9"
6
11
  require "debugger/ruby_core_source"
7
12
 
8
13
  hdrs = proc {
data/ext/rblineprof.c CHANGED
@@ -4,15 +4,19 @@
4
4
  #include <sys/time.h>
5
5
  #include <sys/resource.h>
6
6
 
7
- #ifdef RUBY_VM
7
+ #if defined(RUBY_VM)
8
8
  #include <ruby/re.h>
9
+ #include <ruby/debug.h>
9
10
  #include <ruby/intern.h>
10
- #include <vm_core.h>
11
- #include <iseq.h>
12
11
 
13
- // There's a compile error on 1.9.3. So:
14
- #ifdef RTYPEDDATA_DATA
15
- #define ruby_current_thread ((rb_thread_t *)RTYPEDDATA_DATA(rb_thread_current()))
12
+ #if !defined(HAVE_RB_PROFILE_FRAMES)
13
+ #include <vm_core.h>
14
+ #include <iseq.h>
15
+
16
+ // There's a compile error on 1.9.3. So:
17
+ #ifdef RTYPEDDATA_DATA
18
+ #define ruby_current_thread ((rb_thread_t *)RTYPEDDATA_DATA(rb_thread_current()))
19
+ #endif
16
20
  #endif
17
21
  #else
18
22
  #include <st.h>
@@ -28,6 +32,7 @@ size_t rb_os_allocated_objects(void);
28
32
  #endif
29
33
 
30
34
  static VALUE gc_hook;
35
+ static VALUE sym_total_allocated_object;
31
36
 
32
37
  /*
33
38
  * Time in microseconds
@@ -40,7 +45,7 @@ typedef uint64_t prof_time_t;
40
45
  typedef struct snapshot {
41
46
  prof_time_t wall_time;
42
47
  prof_time_t cpu_time;
43
- #ifdef HAVE_RB_OS_ALLOCATED_OBJECTS
48
+ #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS) || defined(HAVE_RB_GC_STAT)
44
49
  size_t allocated_objects;
45
50
  #endif
46
51
  } snapshot_t;
@@ -78,7 +83,9 @@ typedef struct sourcefile {
78
83
  typedef struct stackframe {
79
84
  // data emitted from Ruby to our profiler hook
80
85
  rb_event_flag_t event;
81
- #ifdef RUBY_VM
86
+ #if defined(HAVE_RB_PROFILE_FRAMES)
87
+ VALUE thread;
88
+ #elif defined(RUBY_VM)
82
89
  rb_thread_t *thread;
83
90
  #else
84
91
  NODE *node;
@@ -162,7 +169,7 @@ snapshot_diff(snapshot_t *t1, snapshot_t *t2)
162
169
  snapshot_t diff = {
163
170
  .wall_time = t1->wall_time - t2->wall_time,
164
171
  .cpu_time = t1->cpu_time - t2->cpu_time,
165
- #ifdef HAVE_RB_OS_ALLOCATED_OBJECTS
172
+ #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS) || defined(HAVE_RB_GC_STAT)
166
173
  .allocated_objects = t1->allocated_objects - t2->allocated_objects
167
174
  #endif
168
175
  };
@@ -175,7 +182,7 @@ snapshot_increment(snapshot_t *s, snapshot_t *inc)
175
182
  {
176
183
  s->wall_time += inc->wall_time;
177
184
  s->cpu_time += inc->cpu_time;
178
- #ifdef HAVE_RB_OS_ALLOCATED_OBJECTS
185
+ #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS) || defined(HAVE_RB_GC_STAT)
179
186
  s->allocated_objects += inc->allocated_objects;
180
187
  #endif
181
188
  }
@@ -277,7 +284,7 @@ sourcefile_lookup(char *filename)
277
284
  return srcfile;
278
285
  }
279
286
 
280
- #ifdef RUBY_VM
287
+ #if defined(RUBY_VM) && !defined(HAVE_RB_PROFILE_FRAMES)
281
288
  /* Find the source of the current method call. This is based on rb_f_caller
282
289
  * in vm_eval.c, and replicates the behavior of `caller.first` from ruby.
283
290
  *
@@ -343,7 +350,17 @@ profiler_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE klass
343
350
  * we use ruby_current_node here to get the caller's file/line info,
344
351
  * (as opposed to node, which points to the callee method being invoked)
345
352
  */
346
- #ifndef RUBY_VM
353
+ #if defined(HAVE_RB_PROFILE_FRAMES)
354
+ int l;
355
+ VALUE iseq, path;
356
+ rb_profile_frames(0, 1, &iseq, &l);
357
+
358
+ /* TODO: use fstring VALUE directly */
359
+ path = rb_profile_frame_absolute_path(iseq);
360
+ if (!RTEST(path)) path = rb_profile_frame_path(iseq);
361
+ file = RSTRING_PTR(path);
362
+ line = l;
363
+ #elif !defined(RUBY_VM)
347
364
  NODE *caller_node = ruby_frame->node;
348
365
  if (!caller_node) return;
349
366
 
@@ -390,8 +407,10 @@ profiler_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE klass
390
407
  snapshot_t now = {
391
408
  .wall_time = walltime_usec(),
392
409
  .cpu_time = cputime_usec(),
393
- #ifdef HAVE_RB_OS_ALLOCATED_OBJECTS
410
+ #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS)
394
411
  .allocated_objects = rb_os_allocated_objects()
412
+ #elif defined(HAVE_RB_GC_STAT)
413
+ .allocated_objects = rb_gc_stat(sym_total_allocated_object)
395
414
  #endif
396
415
  };
397
416
 
@@ -415,7 +434,9 @@ profiler_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE klass
415
434
  frame->line = line;
416
435
  frame->start = now;
417
436
  frame->srcfile = srcfile;
418
- #ifdef RUBY_VM
437
+ #if defined(HAVE_RB_PROFILE_FRAMES)
438
+ frame->thread = rb_thread_current();
439
+ #elif defined(RUBY_VM)
419
440
  frame->thread = th;
420
441
  #else
421
442
  frame->node = node;
@@ -462,7 +483,9 @@ profiler_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE klass
462
483
  if (rblineprof.stack_depth > 0)
463
484
  rblineprof.stack_depth--;
464
485
  } while (frame &&
465
- #ifdef RUBY_VM
486
+ #if defined(HAVE_RB_PROFILE_FRAMES)
487
+ frame->thread != rb_thread_current() &&
488
+ #elif defined(RUBY_VM)
466
489
  frame->thread != th &&
467
490
  #endif
468
491
  /* Break when we find a matching CALL/C_CALL.
@@ -531,7 +554,7 @@ summarize_files(st_data_t key, st_data_t record, st_data_t arg)
531
554
  long i;
532
555
 
533
556
  rb_ary_store(ary, 0, rb_ary_new3(
534
- #ifdef HAVE_RB_OS_ALLOCATED_OBJECTS
557
+ #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS) || defined(HAVE_RB_GC_STAT)
535
558
  7,
536
559
  #else
537
560
  6,
@@ -542,14 +565,14 @@ summarize_files(st_data_t key, st_data_t record, st_data_t arg)
542
565
  ULL2NUM(srcfile->total.cpu_time),
543
566
  ULL2NUM(srcfile->child.cpu_time),
544
567
  ULL2NUM(srcfile->exclusive.cpu_time)
545
- #ifdef HAVE_RB_OS_ALLOCATED_OBJECTS
568
+ #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS) || defined(HAVE_RB_GC_STAT)
546
569
  , ULL2NUM(srcfile->total.allocated_objects)
547
570
  #endif
548
571
  ));
549
572
 
550
573
  for (i=1; i<srcfile->nlines; i++)
551
574
  rb_ary_store(ary, i, rb_ary_new3(
552
- #ifdef HAVE_RB_OS_ALLOCATED_OBJECTS
575
+ #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS) || defined(HAVE_RB_GC_STAT)
553
576
  4,
554
577
  #else
555
578
  3,
@@ -557,7 +580,7 @@ summarize_files(st_data_t key, st_data_t record, st_data_t arg)
557
580
  ULL2NUM(srcfile->lines[i].total.wall_time),
558
581
  ULL2NUM(srcfile->lines[i].total.cpu_time),
559
582
  ULL2NUM(srcfile->lines[i].calls)
560
- #ifdef HAVE_RB_OS_ALLOCATED_OBJECTS
583
+ #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS) || defined(HAVE_RB_GC_STAT)
561
584
  , ULL2NUM(srcfile->lines[i].total.allocated_objects)
562
585
  #endif
563
586
  ));
@@ -621,7 +644,6 @@ lineprof(VALUE self, VALUE filename)
621
644
  rb_ensure(rb_yield, Qnil, lineprof_ensure, self);
622
645
 
623
646
  VALUE ret = rb_hash_new();
624
- VALUE ary = Qnil;
625
647
 
626
648
  if (rblineprof.source_filename) {
627
649
  summarize_files(Qnil, (st_data_t)&rblineprof.file, ret);
@@ -642,6 +664,7 @@ rblineprof_gc_mark()
642
664
  void
643
665
  Init_rblineprof()
644
666
  {
667
+ sym_total_allocated_object = ID2SYM(rb_intern("total_allocated_object"));
645
668
  gc_hook = Data_Wrap_Struct(rb_cObject, rblineprof_gc_mark, NULL, NULL);
646
669
  rb_global_variable(&gc_hook);
647
670
 
data/rblineprof.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rblineprof'
3
- s.version = '0.3.3.beta'
3
+ s.version = '0.3.3'
4
4
  s.homepage = 'http://github.com/tmm1/rblineprof'
5
5
 
6
6
  s.authors = 'Aman Gupta'
@@ -12,5 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.summary = 'line-profiler for ruby'
13
13
  s.description = 'rblineprof shows you lines of code that are slow.'
14
14
 
15
+ s.license = 'MIT'
16
+
15
17
  s.add_dependency 'debugger-ruby_core_source', '~> 1.2'
16
18
  end
data/test.rb CHANGED
@@ -1,4 +1,4 @@
1
- $:.unshift 'ext'
1
+ $:.unshift 'lib'
2
2
  require 'rblineprof'
3
3
 
4
4
  class Obj
@@ -108,16 +108,20 @@ profile = lineprof(/./) do
108
108
  ('a'..'z').to_a
109
109
  end
110
110
 
111
+ allocation_mode = false
112
+
111
113
  File.readlines(file).each_with_index do |line, num|
112
114
  wall, cpu, calls, allocations = profile[file][num+1]
113
115
 
114
- if allocations > 0
115
- printf "% 10d objs | %s", allocations, line
116
- else
117
- printf " | %s", line
118
- end
116
+ if allocation_mode
117
+ if allocations > 0
118
+ printf "% 10d objs | %s", allocations, line
119
+ else
120
+ printf " | %s", line
121
+ end
119
122
 
120
- next
123
+ next
124
+ end
121
125
 
122
126
  if calls && calls > 0
123
127
  printf "% 8.1fms + % 8.1fms (% 5d) | %s", cpu/1000.0, (wall-cpu)/1000.0, calls, line
@@ -0,0 +1,33 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'rblineprof'
3
+ require 'test/unit'
4
+
5
+ class LineProfTest < Test::Unit::TestCase
6
+ def test_real
7
+ profile = lineprof(/./) do
8
+ sleep 0.001
9
+ end
10
+
11
+ line = profile[__FILE__][__LINE__-3]
12
+ assert_in_delta 1000, line[0], 600
13
+ assert_equal 1, line[2]
14
+ end
15
+
16
+ def test_cpu
17
+ profile = lineprof(/./) do
18
+ (fibonacci = Hash.new{ |h,k| h[k] = k < 2 ? k : h[k-1] + h[k-2] })[500]
19
+ end
20
+
21
+ line = profile[__FILE__][__LINE__-3]
22
+ assert_operator line[1], :>=, 800
23
+ end
24
+
25
+ def test_objects
26
+ profile = lineprof(/./) do
27
+ 100.times{ "str" }
28
+ end
29
+
30
+ line = profile[__FILE__][__LINE__-3]
31
+ assert_equal 100, line[3]
32
+ end
33
+ end
metadata CHANGED
@@ -1,30 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rblineprof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3.beta
5
- prerelease: 6
4
+ version: 0.3.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Aman Gupta
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-12 00:00:00.000000000 Z
11
+ date: 2014-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: debugger-ruby_core_source
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '1.2'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '1.2'
30
27
  description: rblineprof shows you lines of code that are slow.
@@ -34,34 +31,40 @@ extensions:
34
31
  - ext/extconf.rb
35
32
  extra_rdoc_files: []
36
33
  files:
34
+ - ".gitignore"
35
+ - Gemfile
36
+ - Gemfile.lock
37
37
  - README.md
38
+ - Rakefile
38
39
  - ext/.gitignore
39
40
  - ext/extconf.rb
40
41
  - ext/rblineprof.c
41
42
  - rblineprof.gemspec
42
43
  - test.rb
44
+ - test/test_lineprof.rb
43
45
  homepage: http://github.com/tmm1/rblineprof
44
- licenses: []
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
45
49
  post_install_message:
46
50
  rdoc_options: []
47
51
  require_paths:
48
52
  - lib
49
53
  required_ruby_version: !ruby/object:Gem::Requirement
50
- none: false
51
54
  requirements:
52
- - - ! '>='
55
+ - - ">="
53
56
  - !ruby/object:Gem::Version
54
57
  version: '0'
55
58
  required_rubygems_version: !ruby/object:Gem::Requirement
56
- none: false
57
59
  requirements:
58
- - - ! '>'
60
+ - - ">="
59
61
  - !ruby/object:Gem::Version
60
- version: 1.3.1
62
+ version: '0'
61
63
  requirements: []
62
64
  rubyforge_project:
63
- rubygems_version: 1.8.23
65
+ rubygems_version: 2.2.0.rc.1
64
66
  signing_key:
65
- specification_version: 3
67
+ specification_version: 4
66
68
  summary: line-profiler for ruby
67
69
  test_files: []
70
+ has_rdoc: