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 <tgrab...@gmail.com> --- 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 Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel