This patch adds a new command-line flag, -Xtrace:invoke, which will output a line whenever a method is called, saying which method of which class that was invoked. Note that the print-out happens from inside the JIT-compiled code itself, so we are certain to get the message every time the function is called (as opposed to e.g. -Xtrace:jit, which will only output a message when a method is compiled).
It looks like this: Running test jvm/PrintTest trace invoke: jvm/PrintTest.main([Ljava/lang/String;)V trace invoke: java/lang/System.<clinit>()V trace invoke: java/lang/VMSystem.makeStandardInputStream()Ljava/io/InputStream; trace invoke: java/io/FileDescriptor.<clinit>()V ... This patch has the potential to help debugging, but please review it so we're sure it can't mess up the generated code. I'm not so steady with the jit/emit stuff yet :-) x86_64 part is untested. Signed-off-by: Vegard Nossum <vegard.nos...@gmail.com> --- arch/x86/emit-code.c | 22 ++++++++++++++++++++++ include/jit/compiler.h | 1 + include/jit/emit-code.h | 2 ++ jit/emit.c | 5 +++++ jit/trace-jit.c | 1 + vm/jato.c | 2 ++ 6 files changed, 33 insertions(+), 0 deletions(-) diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c index 2c55535..b39f91a 100644 --- a/arch/x86/emit-code.c +++ b/arch/x86/emit-code.c @@ -706,6 +706,17 @@ void emit_prolog(struct buffer *buf, unsigned long nr_locals) __emit_sub_imm_reg(buf, nr_locals * sizeof(unsigned long), REG_ESP); } +void emit_trace_invoke(struct buffer *buf, + const char *class, const char *method, const char *type) +{ + __emit_push_imm(buf, (unsigned long) type); + __emit_push_imm(buf, (unsigned long) method); + __emit_push_imm(buf, (unsigned long) class); + __emit_push_imm(buf, (unsigned long) "trace invoke: %s.%s%s\n"); + __emit_call(buf, &printf); + __emit_add_imm_reg(buf, 16, REG_ESP); +} + static void emit_pop_memlocal(struct buffer *buf, struct operand *operand) { unsigned long disp = slot_offset(operand->slot); @@ -1649,6 +1660,17 @@ void emit_prolog(struct buffer *buf, unsigned long nr_locals) REG_RSP); } +void emit_trace_invoke(struct buffer *buf, + const char *class, const char *method, const char *type) +{ + __emit_push_imm(buf, (unsigned long) type); + __emit_push_imm(buf, (unsigned long) method); + __emit_push_imm(buf, (unsigned long) class); + __emit_push_imm(buf, (unsigned long) "trace invoke: %s.%s%s\n"); + __emit_call(buf, &printf); + __emit_add_imm_reg(buf, 32, REG_RSP); +} + void emit_epilog(struct buffer *buf) { emit_leave(buf); diff --git a/include/jit/compiler.h b/include/jit/compiler.h index a42b503..1f991db 100644 --- a/include/jit/compiler.h +++ b/include/jit/compiler.h @@ -94,6 +94,7 @@ extern bool opt_trace_regalloc; extern bool opt_trace_machine_code; extern bool opt_trace_magic_trampoline; extern bool opt_trace_bytecode_offset; +extern bool opt_trace_invoke; void trace_magic_trampoline(struct compilation_unit *); void trace_method(struct compilation_unit *); diff --git a/include/jit/emit-code.h b/include/jit/emit-code.h index bfa89c7..9ed1982 100644 --- a/include/jit/emit-code.h +++ b/include/jit/emit-code.h @@ -26,6 +26,8 @@ extern struct emitter emitters[]; [_insn_type] = { .emit_fn = _fn, .type = _emitter_type } extern void emit_prolog(struct buffer *, unsigned long); +extern void emit_trace_invoke(struct buffer *, + const char *class, const char *method, const char *type) extern void emit_epilog(struct buffer *); extern void emit_trampoline(struct compilation_unit *, void *, struct jit_trampoline *); extern void emit_unwind(struct buffer *); diff --git a/jit/emit.c b/jit/emit.c index 183fe41..4e3e8e6 100644 --- a/jit/emit.c +++ b/jit/emit.c @@ -156,6 +156,11 @@ int emit_machine_code(struct compilation_unit *cu) if (method_is_synchronized(cu->method)) emit_monitorenter(cu); + if (opt_trace_invoke) { + emit_trace_invoke(cu->objcode, cu->method->class->name, + cu->method->name, cu->method->type); + } + for_each_basic_block(bb, &cu->bb_list) emit_body(bb, cu->objcode); diff --git a/jit/trace-jit.c b/jit/trace-jit.c index 266179b..7ab8115 100644 --- a/jit/trace-jit.c +++ b/jit/trace-jit.c @@ -33,6 +33,7 @@ bool opt_trace_regalloc; bool opt_trace_machine_code; bool opt_trace_magic_trampoline; bool opt_trace_bytecode_offset; +bool opt_trace_invoke; void trace_method(struct compilation_unit *cu) { diff --git a/vm/jato.c b/vm/jato.c index 26203af..90ea5d3 100644 --- a/vm/jato.c +++ b/vm/jato.c @@ -248,6 +248,8 @@ main(int argc, char *argv[]) opt_trace_bytecode_offset = true; } else if (!strcmp(argv[i], "-Xtrace:classloader")) { opt_trace_classloader = true; + } else if (!strcmp(argv[i], "-Xtrace:invoke")) { + opt_trace_invoke = true; } else if (!strcmp(argv[i], "-Xtrace:jit")) { opt_trace_method = true; opt_trace_cfg = true; -- 1.6.0.4 ------------------------------------------------------------------------------ _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel