From 73ad86847329d99d51b386f5aba692580d1f8fdc Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 8 Jun 2009 13:32:18 +0300 Subject: [PATCH] perf-map: add support for performance counters This patch adds preliminary support for integrating with Linux kernel performance counters. The perf tool is expected to pick up the anonymous memory [address, size, symbol] mappings when producing reports that we generate. Signed-off-by: Pekka Enberg --- Makefile | 3 ++- include/jit/compiler.h | 17 +++++++++++++ include/jit/perf-map.h | 7 ++++++ jit/compiler.c | 5 ++++ jit/method.c | 7 ++++++ jit/perf-map.c | 56 ++++++++++++++++++++++++++++++++++++++++++ vm/jato.c | 3 +++ 7 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 include/jit/perf-map.h create mode 100644 jit/perf-map.c diff --git a/Makefile b/Makefile index 18a9365d..8daee216 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,8 @@ JIT_OBJS = \ jit/bc-offset-mapping.o \ jit/cu-mapping.o \ jit/method.o \ - jit/nop-bc.o + jit/nop-bc.o \ + jit/perf-map.o VM_OBJS = \ vm/bitset.o \ diff --git a/include/jit/compiler.h b/include/jit/compiler.h index fab4a374..f293c0a5 100644 --- a/include/jit/compiler.h +++ b/include/jit/compiler.h @@ -66,6 +66,23 @@ void free_fixup_site(struct fixup_site *); void trampoline_add_fixup_site(struct jit_trampoline *, struct fixup_site *); unsigned char *fixup_site_addr(struct fixup_site *); +const char *method_symbol(struct methodblock *method, char *symbol, size_t len); + +static inline const char *cu_symbol(struct compilation_unit *cu, char *symbol, size_t len) +{ + return method_symbol(cu->method, symbol, len); +} + +static inline void *cu_native_ptr(struct compilation_unit *cu) +{ + return buffer_ptr(cu->objcode); +} + +static inline unsigned long cu_native_size(struct compilation_unit *cu) +{ + return buffer_offset(cu->objcode); +} + static inline void *method_native_ptr(struct methodblock *method) { return buffer_ptr(method->compilation_unit->objcode); diff --git a/include/jit/perf-map.h b/include/jit/perf-map.h new file mode 100644 index 00000000..8cb8296c --- /dev/null +++ b/include/jit/perf-map.h @@ -0,0 +1,7 @@ +#ifndef JATO_PERF_MAP_H +#define JATO_PERF_MAP_H + +void perf_map_open(void); +void perf_map_append(const char *symbol, unsigned long addr, unsigned long size); + +#endif /* JATO_PERF_MAP_H */ diff --git a/jit/compiler.c b/jit/compiler.c index 33027483..32941ce6 100644 --- a/jit/compiler.c +++ b/jit/compiler.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -26,8 +27,11 @@ static void compile_error(struct compilation_unit *cu, int err) __func__, cu->method->name, cb->name, err); } +#define SYMBOL_LEN 128 + int compile(struct compilation_unit *cu) { + char symbol[SYMBOL_LEN]; int err; if (opt_trace_method) @@ -89,6 +93,7 @@ int compile(struct compilation_unit *cu) cu->is_compiled = true; + perf_map_append(cu_symbol(cu, symbol, SYMBOL_LEN), (unsigned long) cu_native_ptr(cu), cu_native_size(cu)); out: if (err) compile_error(cu, err); diff --git a/jit/method.c b/jit/method.c index bca74026..90970d19 100644 --- a/jit/method.c +++ b/jit/method.c @@ -44,3 +44,10 @@ bool is_jit_method(unsigned long eip) { return eip >= (unsigned long)&etext; } + +const char *method_symbol(struct methodblock *method, char *symbol, size_t size) +{ + snprintf(symbol, size, "%s.%s%s", CLASS_CB(method->class)->name, method->name, method->type); + + return symbol; +} diff --git a/jit/perf-map.c b/jit/perf-map.c new file mode 100644 index 00000000..f80ec6b2 --- /dev/null +++ b/jit/perf-map.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2009 Pekka Enberg + * + * This file is released under the GPL version 2 with the following + * clarification and special exception: + * + * Linking this library statically or dynamically with other modules is + * making a combined work based on this library. Thus, the terms and + * conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give you + * permission to link this library with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under terms + * of your choice, provided that you also meet, for each linked independent + * module, the terms and conditions of the license of that module. An + * independent module is a module which is not derived from or based on + * this library. If you modify this library, you may extend this exception + * to your version of the library, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + * Please refer to the file LICENSE for details. + */ + +#include +#include + +#include +#include +#include +#include + +static pthread_mutex_t perf_mutex = PTHREAD_MUTEX_INITIALIZER; +static FILE *perf_file; + +void perf_map_open(void) +{ + char filename[32]; + pid_t pid; + + pid = getpid(); + sprintf(filename, "perf-%d.map", pid); + + perf_file = fopen(filename, "w"); + if (!perf_file) + die("fopen"); +} + +void perf_map_append(const char *symbol, unsigned long addr, unsigned long size) +{ + pthread_mutex_lock(&perf_mutex); + fprintf(perf_file, "%lx %lx %s\n", addr, size, symbol); + pthread_mutex_unlock(&perf_mutex); +} diff --git a/vm/jato.c b/vm/jato.c index f22dc102..1a43bdae 100644 --- a/vm/jato.c +++ b/vm/jato.c @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef USE_ZIP #define BCP_MESSAGE "" @@ -300,6 +301,8 @@ int main(int argc, char *argv[]) { exe_name = argv[0]; + perf_map_open(); + setup_signal_handlers(); init_cu_mapping(); init_exceptions();