This options enable detailed information dump on method incokation
This includes:
* method's return address and calling method's signature
* target method entry address
* 'this' pointer value and actual class name
* actual invkoation arguments
Example:
trace invoke:
java/lang/StringBuffer.append(Ljava/lang/String;)Ljava/lang/StringBuffer;
entry : 0xa7c76dc0
ret : 0xa7c7640d (java/lang/Throwable.toString()Ljava/lang/String;)
this : 0x81f9a78 (java/lang/StringBuffer)
args :
J_REFERENCE : 0x81f9d68 = ": hello" (java/lang/String)
Signed-off-by: Tomek Grabiec <[email protected]>
---
include/jit/args.h | 1 +
include/jit/compiler.h | 2 +
include/vm/types.h | 1 +
jit/args.c | 32 +++++++++++++
jit/method.c | 8 +++
jit/trace-jit.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++-
vm/jato.c | 3 +
vm/types.c | 22 +++++++++
8 files changed, 186 insertions(+), 1 deletions(-)
diff --git a/include/jit/args.h b/include/jit/args.h
index 9e15a20..265c43f 100644
--- a/include/jit/args.h
+++ b/include/jit/args.h
@@ -7,5 +7,6 @@
struct expression *insert_arg(struct expression *root, struct expression
*expr);
struct expression *convert_args(struct stack *mimic_stack, unsigned long
nr_args);
+const char *parse_method_args(const char *type_str, enum vm_type *vmtype);
#endif
diff --git a/include/jit/compiler.h b/include/jit/compiler.h
index 439a020..7743a89 100644
--- a/include/jit/compiler.h
+++ b/include/jit/compiler.h
@@ -82,6 +82,7 @@ static inline unsigned long cu_native_size(struct
compilation_unit *cu)
}
bool is_native(unsigned long eip);
+bool is_on_heap(unsigned long addr);
void fixup_direct_calls(struct jit_trampoline *trampoline, unsigned long
target);
@@ -95,6 +96,7 @@ extern bool opt_trace_machine_code;
extern bool opt_trace_magic_trampoline;
extern bool opt_trace_bytecode_offset;
extern bool opt_trace_invoke;
+extern bool opt_trace_invoke_dtls;
void trace_magic_trampoline(struct compilation_unit *);
void trace_method(struct compilation_unit *);
diff --git a/include/vm/types.h b/include/vm/types.h
index f5bf6e7..204a6ee 100644
--- a/include/vm/types.h
+++ b/include/vm/types.h
@@ -22,5 +22,6 @@ extern enum vm_type get_method_return_type(char *);
int count_arguments(const char *);
enum vm_type bytecode_type_to_vmtype(int);
int get_vmtype_size(enum vm_type);
+const char *get_vm_type_name(enum vm_type);
#endif
diff --git a/jit/args.c b/jit/args.c
index 9ccac87..131a0d0 100644
--- a/jit/args.c
+++ b/jit/args.c
@@ -61,3 +61,35 @@ convert_args(struct stack *mimic_stack, unsigned long
nr_args)
out:
return args_list;
}
+
+const char *parse_method_args(const char *type_str, enum vm_type *vmtype)
+{
+ char type_name[] = { "X" };
+
+ if (*type_str == '(')
+ type_str++;
+
+ if (*type_str == ')')
+ return NULL;
+
+ if (*type_str == '[') {
+ *vmtype = J_REFERENCE;
+ type_str++;
+
+ if (*type_str != 'L') {
+ return type_str + 1;
+ }
+ }
+
+ if (*type_str == 'L') {
+ ++type_str;
+ while (*(type_str++) != ';')
+ ;
+ *vmtype = J_REFERENCE;
+ } else {
+ type_name[0] = *(type_str++);
+ *vmtype = str_to_type(type_name);
+ }
+
+ return type_str;
+}
diff --git a/jit/method.c b/jit/method.c
index e63b9e5..db1a4a1 100644
--- a/jit/method.c
+++ b/jit/method.c
@@ -49,6 +49,14 @@ bool is_native(unsigned long eip)
return !is_jit_text((void *)eip);
}
+/*
+ * Checks whether given address is on heap
+ */
+bool is_on_heap(unsigned long addr)
+{
+ return addr >= (unsigned long)&end && addr < (unsigned long)sbrk(0);
+}
+
const char *method_symbol(struct vm_method *method, char *symbol, size_t size)
{
snprintf(symbol, size, "%s.%s%s", method->class->name, method->name,
method->type);
diff --git a/jit/trace-jit.c b/jit/trace-jit.c
index 19118f1..fa3a75b 100644
--- a/jit/trace-jit.c
+++ b/jit/trace-jit.c
@@ -12,8 +12,12 @@
#include <jit/basic-block.h>
#include <jit/disassemble.h>
#include <jit/lir-printer.h>
+#include <jit/cu-mapping.h>
#include <jit/statement.h>
#include <jit/vars.h>
+#include <jit/args.h>
+#include <vm/java_lang.h>
+#include <vm/object.h>
#include <vm/buffer.h>
#include <vm/class.h>
@@ -21,7 +25,8 @@
#include <vm/string.h>
#include <vm/vm.h>
-#include <stdbool.h>
+#include <malloc.h>
+#include <stdlib.h>
#include <stdio.h>
bool opt_trace_method;
@@ -34,6 +39,7 @@ bool opt_trace_machine_code;
bool opt_trace_magic_trampoline;
bool opt_trace_bytecode_offset;
bool opt_trace_invoke;
+bool opt_trace_invoke_dtls;
void trace_method(struct compilation_unit *cu)
{
@@ -261,10 +267,120 @@ void trace_magic_trampoline(struct compilation_unit *cu)
cu->method->method_index);
}
+static void print_arg(enum vm_type arg_type, const unsigned long *args,
+ int *arg_index)
+{
+ if (arg_type == J_LONG || arg_type == J_DOUBLE) {
+ unsigned long long value;
+
+ value = *(unsigned long long*)(args + *arg_index);
+ (*arg_index) += 2;
+
+ printf("0x%llx", value);
+ return;
+ }
+
+ printf("0x%lx ", args[*arg_index]);
+
+ if (arg_type == J_REFERENCE) {
+ struct vm_object *obj;
+
+ obj = (struct vm_object *)args[*arg_index];
+
+ if (!obj) {
+ printf("null");
+ goto out;
+ }
+
+ if (!is_on_heap((unsigned long)obj)) {
+ printf("*** pointer not on heap ***");
+ goto out;
+ }
+
+ if (obj->class == vm_java_lang_String) {
+ char *str;
+
+ str = vm_string_to_cstr(obj);
+ printf("= \"%s\"", str);
+ free(str);
+ }
+
+ printf(" (%s)", obj->class->name);
+ }
+
+ out:
+ (*arg_index)++;
+ printf("\n");
+}
+
+static void trace_invoke_args(struct vm_method *vmm,
+ struct jit_stack_frame *frame)
+{
+ enum vm_type arg_type;
+ const char *type_str;
+ int arg_index;
+
+ arg_index = 0;
+
+ if (!vm_method_is_static(vmm)) {
+ printf("\tthis\t: ");
+ print_arg(J_REFERENCE, frame->args, &arg_index);
+ }
+
+ type_str = vmm->type;
+
+ if (!strncmp(type_str, "()", 2)) {
+ printf("\targs\t: none\n");
+ return;
+ }
+
+ printf("\targs\t:\n");
+
+ while ((type_str = parse_method_args(type_str, &arg_type))) {
+ printf("\t %-12s: ", get_vm_type_name(arg_type));
+ print_arg(arg_type, frame->args, &arg_index);
+ }
+}
+
+static void trace_return_address(struct jit_stack_frame *frame)
+{
+ printf("\tret\t: %p", (void*)frame->return_address);
+
+ if (is_native(frame->return_address)) {
+ printf(" (native)\n");
+ } else {
+ struct compilation_unit *cu;
+ struct vm_method *vmm;
+ struct vm_class *vmc;
+
+ cu = get_cu_from_native_addr(frame->return_address);
+ if (!cu) {
+ printf(" (no compilation unit mapping)\n");
+ return;
+ }
+
+ vmm = cu->method;;
+ vmc = vmm->class;
+
+ printf(" (%s.%s%s)\n", vmc->name, vmm->name, vmm->type );
+ }
+}
+
+
void trace_invoke(struct compilation_unit *cu)
{
struct vm_method *vmm = cu->method;
struct vm_class *vmc = vmm->class;
printf("trace invoke: %s.%s%s\n", vmc->name, vmm->name, vmm->type);
+
+ if (opt_trace_invoke_dtls) {
+ struct jit_stack_frame *frame;
+
+ frame = __builtin_frame_address(1);
+
+ printf("\tentry\t: %p\n", buffer_ptr(cu->objcode));
+ trace_return_address(frame);
+ trace_invoke_args(vmm, frame);
+ }
}
diff --git a/vm/jato.c b/vm/jato.c
index 52ddf5b..3c17cdd 100644
--- a/vm/jato.c
+++ b/vm/jato.c
@@ -415,6 +415,9 @@ main(int argc, char *argv[])
opt_trace_classloader = true;
} else if (!strcmp(argv[i], "-Xtrace:invoke")) {
opt_trace_invoke = true;
+ } else if (!strcmp(argv[i], "-Xtrace:invoke-dtls")) {
+ opt_trace_invoke = true;
+ opt_trace_invoke_dtls = true;
} else if (!strcmp(argv[i], "-Xtrace:jit")) {
opt_trace_method = true;
opt_trace_cfg = true;
diff --git a/vm/types.c b/vm/types.c
index 9cb72b4..8d5ab0b 100644
--- a/vm/types.c
+++ b/vm/types.c
@@ -1,3 +1,4 @@
+#include <vm/system.h>
#include <vm/types.h>
#include <vm/die.h>
#include <vm/vm.h>
@@ -171,3 +172,24 @@ int get_vmtype_size(enum vm_type type)
error("type has no size");
}
}
+
+static const char *vm_type_names[] = {
+ [J_VOID] = "J_VOID",
+ [J_REFERENCE] = "J_REFERENCE",
+ [J_BYTE] = "J_BYTE",
+ [J_SHORT] = "J_SHORT",
+ [J_INT] = "J_INT",
+ [J_LONG] = "J_LONG",
+ [J_CHAR] = "J_CHAR",
+ [J_FLOAT] = "J_FLOAT",
+ [J_DOUBLE] = "J_DOUBLE",
+ [J_BOOLEAN] = "J_BOOLEAN",
+ [J_RETURN_ADDRESS] = "J_RETURN_ADDRESS"
+};
+
+const char *get_vm_type_name(enum vm_type type) {
+ if (type < 0 || type >= ARRAY_SIZE(vm_type_names))
+ return NULL;
+
+ return vm_type_names[type];
+}
--
1.6.0.6
------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel