diff options
author | Mike Pall <mike> | 2010-05-01 04:27:14 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-05-01 04:27:14 +0200 |
commit | 8fa1db826c095adcc45d961e6f6870406d69d49d (patch) | |
tree | ef3f517361fa4dadbf1bbefa0d3d35323a5c0068 /src | |
parent | f28a42c9239142441bf3e3149f5d76efab71aac2 (diff) | |
download | luajit-8fa1db826c095adcc45d961e6f6870406d69d49d.tar.gz luajit-8fa1db826c095adcc45d961e6f6870406d69d49d.tar.bz2 luajit-8fa1db826c095adcc45d961e6f6870406d69d49d.zip |
Create symbol table of JIT-compiled code for use with Linux perf tools.
Enable with: -DLUAJIT_USE_PERFTOOLS
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_trace.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/lj_trace.c b/src/lj_trace.c index 8419c9bb..fc531a19 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
@@ -81,6 +81,44 @@ static TraceNo trace_findfree(jit_State *J) | |||
81 | memcpy(p, J->cur.field, J->cur.szfield*sizeof(tp)); \ | 81 | memcpy(p, J->cur.field, J->cur.szfield*sizeof(tp)); \ |
82 | p += J->cur.szfield*sizeof(tp); | 82 | p += J->cur.szfield*sizeof(tp); |
83 | 83 | ||
84 | #ifdef LUAJIT_USE_PERFTOOLS | ||
85 | /* | ||
86 | ** Create symbol table of JIT-compiled code. For use with Linux perf tools. | ||
87 | ** Example usage: | ||
88 | ** perf record -f -e cycles luajit test.lua | ||
89 | ** perf report -s symbol | ||
90 | ** rm perf.data /tmp/perf-*.map | ||
91 | */ | ||
92 | #include <stdio.h> | ||
93 | #include <unistd.h> | ||
94 | |||
95 | static void perftools_addtrace(GCtrace *T) | ||
96 | { | ||
97 | static FILE *fp; | ||
98 | GCproto *pt = &gcref(T->startpt)->pt; | ||
99 | uintptr_t pcofs = (uintptr_t)(T->snap[0].mapofs+T->snap[0].nent); | ||
100 | const BCIns *startpc = snap_pc(T->snapmap[pcofs]); | ||
101 | const char *name = strdata(proto_chunkname(pt)); | ||
102 | BCLine lineno; | ||
103 | if (name[0] == '@' || name[0] == '=') | ||
104 | name++; | ||
105 | else | ||
106 | name = "(string)"; | ||
107 | if (startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc) | ||
108 | lineno = proto_line(pt, proto_bcpos(pt, startpc)); | ||
109 | else | ||
110 | lineno = proto_line(pt, 0); /* Wrong, but better than nothing. */ | ||
111 | if (!fp) { | ||
112 | char fname[40]; | ||
113 | sprintf(fname, "/tmp/perf-%d.map", getpid()); | ||
114 | if (!(fp = fopen(fname, "w"))) return; | ||
115 | setlinebuf(fp); | ||
116 | } | ||
117 | fprintf(fp, "%lx %x TRACE_%d::%s:%u\n", | ||
118 | (long)T->mcode, T->szmcode, T->traceno, name, lineno); | ||
119 | } | ||
120 | #endif | ||
121 | |||
84 | /* Save current trace by copying and compacting it. */ | 122 | /* Save current trace by copying and compacting it. */ |
85 | static void trace_save(jit_State *J) | 123 | static void trace_save(jit_State *J) |
86 | { | 124 | { |
@@ -105,6 +143,9 @@ static void trace_save(jit_State *J) | |||
105 | setgcrefp(J->trace[T->traceno], T); | 143 | setgcrefp(J->trace[T->traceno], T); |
106 | lj_gc_barriertrace(J2G(J), T->traceno); | 144 | lj_gc_barriertrace(J2G(J), T->traceno); |
107 | lj_gdbjit_addtrace(J, T); | 145 | lj_gdbjit_addtrace(J, T); |
146 | #ifdef LUAJIT_USE_PERFTOOLS | ||
147 | perftools_addtrace(T); | ||
148 | #endif | ||
108 | } | 149 | } |
109 | 150 | ||
110 | void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T) | 151 | void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T) |