perftools.rb 0.4.0 → 0.4.2
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 +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
|