perftools.rb 0.4.0 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -0
- data/ext/extconf.rb +4 -2
- data/ext/perftools.c +155 -4
- data/objalloc_tests/Makefile +7 -0
- data/objalloc_tests/trap.c +103 -0
- data/patches/perftools-objects.patch +91 -0
- data/perftools.rb.gemspec +3 -18
- metadata +21 -6
data/README
CHANGED
data/ext/extconf.rb
CHANGED
@@ -46,7 +46,8 @@ Dir.chdir('src') do
|
|
46
46
|
['perftools-osx', RUBY_PLATFORM =~ /darwin/],
|
47
47
|
['perftools-osx-106', RUBY_PLATFORM =~ /darwin10/],
|
48
48
|
['perftools-debug', true],
|
49
|
-
['perftools-realtime', true]
|
49
|
+
['perftools-realtime', true],
|
50
|
+
['perftools-objects', true]
|
50
51
|
].each do |patch, apply|
|
51
52
|
if apply
|
52
53
|
sys("patch -p1 < ../../../patches/#{patch}.patch")
|
@@ -80,7 +81,7 @@ def add_define(name)
|
|
80
81
|
end
|
81
82
|
|
82
83
|
case RUBY_PLATFORM
|
83
|
-
when /darwin/, /linux/
|
84
|
+
when /darwin/, /linux/, /freebsd/
|
84
85
|
CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
|
85
86
|
end
|
86
87
|
|
@@ -88,6 +89,7 @@ if RUBY_VERSION >= "1.9"
|
|
88
89
|
add_define 'RUBY19'
|
89
90
|
|
90
91
|
hdrs = proc {
|
92
|
+
have_header("method.h") # exists on 1.9.2
|
91
93
|
have_header("vm_core.h") and
|
92
94
|
have_header("iseq.h") and
|
93
95
|
have_header("insns.inc") and
|
data/ext/perftools.c
CHANGED
@@ -5,6 +5,7 @@ void ProfilerGcMark(void (*cb)(VALUE));
|
|
5
5
|
int ProfilerStart(const char*);
|
6
6
|
void ProfilerStop();
|
7
7
|
void ProfilerFlush();
|
8
|
+
void ProfilerRecord(int, void*, void*);
|
8
9
|
|
9
10
|
static VALUE Iallocate;
|
10
11
|
static VALUE I__send__;
|
@@ -147,8 +148,13 @@ static VALUE Isend;
|
|
147
148
|
case VM_FRAME_MAGIC_METHOD:
|
148
149
|
case VM_FRAME_MAGIC_CFUNC:
|
149
150
|
self = cfp->self;
|
151
|
+
#ifdef HAVE_METHOD_H
|
152
|
+
klass = cfp->me->klass;
|
153
|
+
method = cfp->me->called_id;
|
154
|
+
#else
|
150
155
|
klass = cfp->method_class;
|
151
156
|
method = cfp->method_id;
|
157
|
+
#endif
|
152
158
|
SAVE_FRAME();
|
153
159
|
break;
|
154
160
|
}
|
@@ -193,18 +199,23 @@ static VALUE Isend;
|
|
193
199
|
#endif
|
194
200
|
#endif
|
195
201
|
|
202
|
+
static VALUE objprofiler_setup();
|
203
|
+
static VALUE objprofiler_teardown();
|
204
|
+
|
205
|
+
/* CpuProfiler */
|
206
|
+
|
196
207
|
static VALUE cPerfTools;
|
197
208
|
static VALUE cCpuProfiler;
|
198
209
|
static VALUE bProfilerRunning;
|
199
210
|
static VALUE gc_hook;
|
200
211
|
|
201
|
-
VALUE
|
212
|
+
static VALUE
|
202
213
|
cpuprofiler_running_p(VALUE self)
|
203
214
|
{
|
204
215
|
return bProfilerRunning;
|
205
216
|
}
|
206
217
|
|
207
|
-
VALUE
|
218
|
+
static VALUE
|
208
219
|
cpuprofiler_stop(VALUE self)
|
209
220
|
{
|
210
221
|
if (!bProfilerRunning)
|
@@ -213,10 +224,14 @@ cpuprofiler_stop(VALUE self)
|
|
213
224
|
bProfilerRunning = Qfalse;
|
214
225
|
ProfilerStop();
|
215
226
|
ProfilerFlush();
|
227
|
+
|
228
|
+
if (getenv("CPUPROFILE_OBJECTS"))
|
229
|
+
objprofiler_teardown();
|
230
|
+
|
216
231
|
return Qtrue;
|
217
232
|
}
|
218
233
|
|
219
|
-
VALUE
|
234
|
+
static VALUE
|
220
235
|
cpuprofiler_start(VALUE self, VALUE filename)
|
221
236
|
{
|
222
237
|
StringValue(filename);
|
@@ -224,6 +239,9 @@ cpuprofiler_start(VALUE self, VALUE filename)
|
|
224
239
|
if (bProfilerRunning)
|
225
240
|
return Qfalse;
|
226
241
|
|
242
|
+
if (getenv("CPUPROFILE_OBJECTS"))
|
243
|
+
objprofiler_setup();
|
244
|
+
|
227
245
|
ProfilerStart(RSTRING_PTR(filename));
|
228
246
|
bProfilerRunning = Qtrue;
|
229
247
|
|
@@ -241,20 +259,153 @@ cpuprofiler_gc_mark()
|
|
241
259
|
ProfilerGcMark(rb_gc_mark);
|
242
260
|
}
|
243
261
|
|
262
|
+
/* ObjProfiler */
|
263
|
+
|
264
|
+
#ifndef _GNU_SOURCE
|
265
|
+
#define _GNU_SOURCE
|
266
|
+
#endif
|
267
|
+
#ifndef _XOPEN_SOURCE
|
268
|
+
#define _XOPEN_SOURCE 600
|
269
|
+
#endif
|
270
|
+
|
271
|
+
#include <assert.h>
|
272
|
+
#include <ucontext.h>
|
273
|
+
#include <unistd.h>
|
274
|
+
#include <signal.h>
|
275
|
+
#include <stdio.h>
|
276
|
+
#include <stdlib.h>
|
277
|
+
#include <string.h>
|
278
|
+
#include <sys/mman.h>
|
279
|
+
|
280
|
+
static VALUE bObjProfilerRunning;
|
281
|
+
#define NUM_ORIG_BYTES 2
|
282
|
+
|
283
|
+
struct {
|
284
|
+
void *location;
|
285
|
+
unsigned char value;
|
286
|
+
} orig_bytes[NUM_ORIG_BYTES];
|
287
|
+
|
288
|
+
static inline void *
|
289
|
+
page_align(void *addr) {
|
290
|
+
assert(addr != NULL);
|
291
|
+
return (void *)((size_t)addr & ~(0xFFFF));
|
292
|
+
}
|
293
|
+
|
294
|
+
static void
|
295
|
+
copy_instructions(void *dest, void *src, size_t count) {
|
296
|
+
assert(dest != NULL);
|
297
|
+
assert(src != NULL);
|
298
|
+
|
299
|
+
void *aligned_addr = page_align(dest);
|
300
|
+
if (mprotect(aligned_addr, (dest - aligned_addr) + count, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
|
301
|
+
perror("mprotect");
|
302
|
+
memcpy(dest, src, count);
|
303
|
+
}
|
304
|
+
|
305
|
+
static inline void**
|
306
|
+
uc_get_ip(ucontext_t *uc) {
|
307
|
+
#if defined(__FreeBSD__)
|
308
|
+
return (void**)&uc->uc_mcontext.mc_rip;
|
309
|
+
#elif defined(__dietlibc__)
|
310
|
+
return (void**)&uc->uc_mcontext.rip;
|
311
|
+
#elif defined(__APPLE__)
|
312
|
+
return (void**)&uc->uc_mcontext->__ss.__rip;
|
313
|
+
#else
|
314
|
+
return (void**)&uc->uc_mcontext.gregs[REG_RIP];
|
315
|
+
#endif
|
316
|
+
}
|
317
|
+
|
318
|
+
static void
|
319
|
+
trap_handler(int sig, siginfo_t *info, void *data) {
|
320
|
+
int i;
|
321
|
+
ucontext_t *uc = (ucontext_t *)data;
|
322
|
+
void **ip = uc_get_ip(uc);
|
323
|
+
|
324
|
+
// printf("signal: %d, addr: %p, ip: %p\n", signal, info->si_addr, *ip);
|
325
|
+
|
326
|
+
for (i=0; i<NUM_ORIG_BYTES; i++) {
|
327
|
+
if (orig_bytes[i].location == *ip-1) {
|
328
|
+
// restore original byte
|
329
|
+
copy_instructions(orig_bytes[i].location, &orig_bytes[i].value, 1);
|
330
|
+
|
331
|
+
// setup next breakpoint
|
332
|
+
copy_instructions(orig_bytes[(i+1)%NUM_ORIG_BYTES].location, "\xCC", 1);
|
333
|
+
|
334
|
+
// first breakpoint is the notification
|
335
|
+
if (i == 0)
|
336
|
+
ProfilerRecord(sig, info, data);
|
337
|
+
|
338
|
+
// reset instruction pointer
|
339
|
+
*ip -= 1;
|
340
|
+
|
341
|
+
break;
|
342
|
+
}
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
346
|
+
static VALUE
|
347
|
+
objprofiler_setup()
|
348
|
+
{
|
349
|
+
if (bObjProfilerRunning)
|
350
|
+
return Qtrue;
|
351
|
+
|
352
|
+
int i;
|
353
|
+
struct sigaction sig = { .sa_sigaction = trap_handler, .sa_flags = SA_SIGINFO };
|
354
|
+
sigemptyset(&sig.sa_mask);
|
355
|
+
sigaction(SIGTRAP, &sig, NULL);
|
356
|
+
|
357
|
+
for (i=0; i<NUM_ORIG_BYTES; i++) {
|
358
|
+
orig_bytes[i].location = rb_newobj + i;
|
359
|
+
orig_bytes[i].value = ((unsigned char*)rb_newobj)[i];
|
360
|
+
copy_instructions(rb_newobj + i, "\xCC", 1);
|
361
|
+
}
|
362
|
+
|
363
|
+
// setenv("CPUPROFILE_OBJECTS", "1", 1);
|
364
|
+
bObjProfilerRunning = Qtrue;
|
365
|
+
return Qtrue;
|
366
|
+
}
|
367
|
+
|
368
|
+
static VALUE
|
369
|
+
objprofiler_teardown()
|
370
|
+
{
|
371
|
+
if (!bObjProfilerRunning)
|
372
|
+
return Qfalse;
|
373
|
+
|
374
|
+
int i;
|
375
|
+
struct sigaction sig = { .sa_handler = SIG_IGN };
|
376
|
+
sigemptyset(&sig.sa_mask);
|
377
|
+
sigaction(SIGTRAP, &sig, NULL);
|
378
|
+
|
379
|
+
for (i=0; i<NUM_ORIG_BYTES; i++) {
|
380
|
+
copy_instructions(orig_bytes[i].location, &orig_bytes[i].value, 1);
|
381
|
+
}
|
382
|
+
|
383
|
+
// unsetenv("CPUPROFILE_OBJECTS");
|
384
|
+
bObjProfilerRunning = Qfalse;
|
385
|
+
return Qtrue;
|
386
|
+
}
|
387
|
+
|
388
|
+
/* Init */
|
389
|
+
|
244
390
|
void
|
245
391
|
Init_perftools()
|
246
392
|
{
|
247
393
|
cPerfTools = rb_define_class("PerfTools", rb_cObject);
|
248
394
|
cCpuProfiler = rb_define_class_under(cPerfTools, "CpuProfiler", rb_cObject);
|
249
|
-
|
395
|
+
|
250
396
|
Iallocate = rb_intern("allocate");
|
251
397
|
I__send__ = rb_intern("__send__");
|
252
398
|
Isend = rb_intern("send");
|
253
399
|
|
400
|
+
bObjProfilerRunning = bProfilerRunning = Qfalse;
|
401
|
+
|
254
402
|
rb_define_singleton_method(cCpuProfiler, "running?", cpuprofiler_running_p, 0);
|
255
403
|
rb_define_singleton_method(cCpuProfiler, "start", cpuprofiler_start, 1);
|
256
404
|
rb_define_singleton_method(cCpuProfiler, "stop", cpuprofiler_stop, 0);
|
257
405
|
|
258
406
|
gc_hook = Data_Wrap_Struct(cCpuProfiler, cpuprofiler_gc_mark, NULL, NULL);
|
259
407
|
rb_global_variable(&gc_hook);
|
408
|
+
|
409
|
+
if (getenv("CPUPROFILE") && getenv("CPUPROFILE_OBJECTS"))
|
410
|
+
objprofiler_setup();
|
260
411
|
}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#define _GNU_SOURCE
|
2
|
+
#define _XOPEN_SOURCE 600
|
3
|
+
|
4
|
+
#include <assert.h>
|
5
|
+
#include <ucontext.h>
|
6
|
+
#include <unistd.h>
|
7
|
+
#include <signal.h>
|
8
|
+
#include <stdio.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <string.h>
|
11
|
+
#include <sys/mman.h>
|
12
|
+
|
13
|
+
|
14
|
+
void
|
15
|
+
func() {
|
16
|
+
printf("hi\n");
|
17
|
+
}
|
18
|
+
|
19
|
+
|
20
|
+
static inline void *
|
21
|
+
page_align(void *addr) {
|
22
|
+
assert(addr != NULL);
|
23
|
+
return (void *)((size_t)addr & ~(0xFFFF));
|
24
|
+
}
|
25
|
+
|
26
|
+
static void
|
27
|
+
copy_instructions(void *dest, void *src, size_t count) {
|
28
|
+
assert(dest != NULL);
|
29
|
+
assert(src != NULL);
|
30
|
+
|
31
|
+
void *aligned_addr = page_align(dest);
|
32
|
+
if (mprotect(aligned_addr, (dest - aligned_addr) + count, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
|
33
|
+
perror("mprotect");
|
34
|
+
memcpy(dest, src, count);
|
35
|
+
}
|
36
|
+
|
37
|
+
#define NUM_ORIG_BYTES 2
|
38
|
+
struct {
|
39
|
+
void *location;
|
40
|
+
unsigned char value;
|
41
|
+
} orig_bytes[NUM_ORIG_BYTES];
|
42
|
+
|
43
|
+
static inline void**
|
44
|
+
uc_get_ip(ucontext_t *uc) {
|
45
|
+
#if defined(__FreeBSD__)
|
46
|
+
return (void**)&uc->uc_mcontext.mc_rip;
|
47
|
+
#elif defined(__dietlibc__)
|
48
|
+
return (void**)&uc->uc_mcontext.rip;
|
49
|
+
#elif defined(__APPLE__)
|
50
|
+
return (void**)&uc->uc_mcontext->__ss.__rip;
|
51
|
+
#else
|
52
|
+
return (void**)&uc->uc_mcontext.gregs[REG_RIP];
|
53
|
+
#endif
|
54
|
+
}
|
55
|
+
|
56
|
+
static void
|
57
|
+
trap_handler(int signal, siginfo_t *info, void *data) {
|
58
|
+
int i;
|
59
|
+
ucontext_t *uc = (ucontext_t *)data;
|
60
|
+
void **ip = uc_get_ip(uc);
|
61
|
+
|
62
|
+
// printf("signal: %d, addr: %p, ip: %p\n", signal, info->si_addr, *ip);
|
63
|
+
|
64
|
+
for (i=0; i<NUM_ORIG_BYTES; i++) {
|
65
|
+
if (orig_bytes[i].location == *ip-1) {
|
66
|
+
// restore original byte
|
67
|
+
copy_instructions(orig_bytes[i].location, &orig_bytes[i].value, 1);
|
68
|
+
|
69
|
+
// setup next breakpoint
|
70
|
+
copy_instructions(orig_bytes[(i+1)%NUM_ORIG_BYTES].location, "\xCC", 1);
|
71
|
+
|
72
|
+
// first breakpoint is the notification
|
73
|
+
if (i == 0)
|
74
|
+
printf(" ---> YOU'RE CALLING FUNC()\n");
|
75
|
+
|
76
|
+
// reset instruction pointer
|
77
|
+
*ip -= 1;
|
78
|
+
|
79
|
+
break;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
int
|
85
|
+
main() {
|
86
|
+
int i;
|
87
|
+
struct sigaction sig = { .sa_sigaction = trap_handler, .sa_flags = SA_SIGINFO };
|
88
|
+
sigemptyset(&sig.sa_mask);
|
89
|
+
sigaction(SIGTRAP, &sig, NULL);
|
90
|
+
|
91
|
+
for (i=0; i<NUM_ORIG_BYTES; i++) {
|
92
|
+
orig_bytes[i].location = func + i;
|
93
|
+
orig_bytes[i].value = ((unsigned char*)func)[i];
|
94
|
+
copy_instructions(func + i, "\xCC", 1);
|
95
|
+
}
|
96
|
+
|
97
|
+
printf("func: %p\n", func);
|
98
|
+
|
99
|
+
for (i=0; i<10; i++)
|
100
|
+
func();
|
101
|
+
|
102
|
+
return 0;
|
103
|
+
}
|
@@ -0,0 +1,91 @@
|
|
1
|
+
commit 5ffd87871619a750ad19e247670a0887a6d38fbd
|
2
|
+
Author: Aman Gupta <aman@tmm1.net>
|
3
|
+
Date: Sun Aug 1 18:50:38 2010 -0700
|
4
|
+
|
5
|
+
perftools-objects
|
6
|
+
|
7
|
+
diff --git a/src/profile-handler.cc b/src/profile-handler.cc
|
8
|
+
index 619b980..2ecf2c0 100644
|
9
|
+
--- a/src/profile-handler.cc
|
10
|
+
+++ b/src/profile-handler.cc
|
11
|
+
@@ -402,6 +402,8 @@ void ProfileHandler::GetState(ProfileHandlerState* state) {
|
12
|
+
}
|
13
|
+
|
14
|
+
void ProfileHandler::StartTimer() {
|
15
|
+
+ if (getenv("CPUPROFILE_OBJECTS")) return;
|
16
|
+
+
|
17
|
+
struct itimerval timer;
|
18
|
+
timer.it_interval.tv_sec = 0;
|
19
|
+
timer.it_interval.tv_usec = 1000000 / frequency_;
|
20
|
+
@@ -410,12 +412,16 @@ void ProfileHandler::StartTimer() {
|
21
|
+
}
|
22
|
+
|
23
|
+
void ProfileHandler::StopTimer() {
|
24
|
+
+ if (getenv("CPUPROFILE_OBJECTS")) return;
|
25
|
+
+
|
26
|
+
struct itimerval timer;
|
27
|
+
memset(&timer, 0, sizeof timer);
|
28
|
+
setitimer(realtime_ ? ITIMER_REAL : ITIMER_PROF, &timer, 0);
|
29
|
+
}
|
30
|
+
|
31
|
+
bool ProfileHandler::IsTimerRunning() {
|
32
|
+
+ if (getenv("CPUPROFILE_OBJECTS")) return false;
|
33
|
+
+
|
34
|
+
struct itimerval current_timer;
|
35
|
+
RAW_CHECK(0 == getitimer(realtime_ ? ITIMER_REAL : ITIMER_PROF, ¤t_timer), "getitimer");
|
36
|
+
return (current_timer.it_value.tv_sec != 0 ||
|
37
|
+
@@ -423,6 +429,8 @@ bool ProfileHandler::IsTimerRunning() {
|
38
|
+
}
|
39
|
+
|
40
|
+
void ProfileHandler::EnableHandler() {
|
41
|
+
+ if (getenv("CPUPROFILE_OBJECTS")) return;
|
42
|
+
+
|
43
|
+
struct sigaction sa;
|
44
|
+
sa.sa_sigaction = SignalHandler;
|
45
|
+
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
46
|
+
@@ -431,6 +439,8 @@ void ProfileHandler::EnableHandler() {
|
47
|
+
}
|
48
|
+
|
49
|
+
void ProfileHandler::DisableHandler() {
|
50
|
+
+ if (getenv("CPUPROFILE_OBJECTS")) return;
|
51
|
+
+
|
52
|
+
struct sigaction sa;
|
53
|
+
sa.sa_handler = SIG_IGN;
|
54
|
+
sa.sa_flags = SA_RESTART;
|
55
|
+
diff --git a/src/profiler.cc b/src/profiler.cc
|
56
|
+
index 37234b2..905288f 100644
|
57
|
+
--- a/src/profiler.cc
|
58
|
+
+++ b/src/profiler.cc
|
59
|
+
@@ -97,6 +97,10 @@ class CpuProfiler {
|
60
|
+
|
61
|
+
static CpuProfiler instance_;
|
62
|
+
|
63
|
+
+ // Signal handler that records the interrupted pc in the profile data.
|
64
|
+
+ static void prof_handler(int sig, siginfo_t*, void* signal_ucontext,
|
65
|
+
+ void* cpu_profiler);
|
66
|
+
+
|
67
|
+
private:
|
68
|
+
// This lock implements the locking requirements described in the ProfileData
|
69
|
+
// documentation, specifically:
|
70
|
+
@@ -125,10 +129,6 @@ class CpuProfiler {
|
71
|
+
|
72
|
+
// Disables receiving SIGPROF interrupt.
|
73
|
+
void DisableHandler();
|
74
|
+
-
|
75
|
+
- // Signal handler that records the interrupted pc in the profile data.
|
76
|
+
- static void prof_handler(int sig, siginfo_t*, void* signal_ucontext,
|
77
|
+
- void* cpu_profiler);
|
78
|
+
};
|
79
|
+
|
80
|
+
// Profile data structure singleton: Constructor will check to see if
|
81
|
+
@@ -318,6 +318,10 @@ extern "C" PERFTOOLS_DLL_DECL void ProfilerFlush() {
|
82
|
+
extern "C" PERFTOOLS_DLL_DECL void ProfilerGcMark(void (*cb)(VALUE)) {
|
83
|
+
CpuProfiler::instance_.GcMark(cb);
|
84
|
+
}
|
85
|
+
+
|
86
|
+
+extern "C" PERFTOOLS_DLL_DECL void ProfilerRecord(int sig, siginfo_t* info, void* signal_ucontext) {
|
87
|
+
+ CpuProfiler::prof_handler(sig, info, signal_ucontext, (void*)&CpuProfiler::instance_);
|
88
|
+
+}
|
89
|
+
#endif
|
90
|
+
|
91
|
+
extern "C" PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads() {
|
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.4.
|
4
|
-
s.date = '
|
3
|
+
s.version = '0.4.2'
|
4
|
+
s.date = '2010-08-01'
|
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'
|
@@ -17,20 +17,5 @@ spec = Gem::Specification.new do |s|
|
|
17
17
|
s.executables << 'pprof.rb'
|
18
18
|
|
19
19
|
# ruby -rpp -e' pp `git ls-files | grep -v examples`.split("\n").sort '
|
20
|
-
s.files =
|
21
|
-
"README",
|
22
|
-
"bin/pprof.rb",
|
23
|
-
"ext/extconf.rb",
|
24
|
-
"ext/perftools.c",
|
25
|
-
"ext/src/google-perftools-1.4.tar.gz",
|
26
|
-
"patches/perftools-debug.patch",
|
27
|
-
"patches/perftools-gc.patch",
|
28
|
-
"patches/perftools-osx-106.patch",
|
29
|
-
"patches/perftools-osx.patch",
|
30
|
-
"patches/perftools-pprof.patch",
|
31
|
-
"patches/perftools-realtime.patch",
|
32
|
-
"patches/perftools-notests.patch",
|
33
|
-
"patches/perftools.patch",
|
34
|
-
"perftools.rb.gemspec"
|
35
|
-
]
|
20
|
+
s.files = `git ls-files`.split("\n").reject{ |f| f =~ /^examples/ }
|
36
21
|
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perftools.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 11
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
- 2
|
10
|
+
version: 0.4.2
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Aman Gupta
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-08-01 00:00:00 -07:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -27,13 +33,16 @@ files:
|
|
27
33
|
- ext/extconf.rb
|
28
34
|
- ext/perftools.c
|
29
35
|
- ext/src/google-perftools-1.4.tar.gz
|
36
|
+
- objalloc_tests/Makefile
|
37
|
+
- objalloc_tests/trap.c
|
30
38
|
- patches/perftools-debug.patch
|
31
39
|
- patches/perftools-gc.patch
|
40
|
+
- patches/perftools-notests.patch
|
41
|
+
- patches/perftools-objects.patch
|
32
42
|
- patches/perftools-osx-106.patch
|
33
43
|
- patches/perftools-osx.patch
|
34
44
|
- patches/perftools-pprof.patch
|
35
45
|
- patches/perftools-realtime.patch
|
36
|
-
- patches/perftools-notests.patch
|
37
46
|
- patches/perftools.patch
|
38
47
|
- perftools.rb.gemspec
|
39
48
|
has_rdoc: true
|
@@ -46,21 +55,27 @@ rdoc_options: []
|
|
46
55
|
require_paths:
|
47
56
|
- lib
|
48
57
|
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
49
59
|
requirements:
|
50
60
|
- - ">="
|
51
61
|
- !ruby/object:Gem::Version
|
62
|
+
hash: 3
|
63
|
+
segments:
|
64
|
+
- 0
|
52
65
|
version: "0"
|
53
|
-
version:
|
54
66
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
55
68
|
requirements:
|
56
69
|
- - ">="
|
57
70
|
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
58
74
|
version: "0"
|
59
|
-
version:
|
60
75
|
requirements: []
|
61
76
|
|
62
77
|
rubyforge_project: perftools-rb
|
63
|
-
rubygems_version: 1.3.
|
78
|
+
rubygems_version: 1.3.7
|
64
79
|
signing_key:
|
65
80
|
specification_version: 3
|
66
81
|
summary: google-perftools for ruby code
|