rblineprof 0.3.3.beta → 0.3.3

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.
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: