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

Reply via email to