This lets us trace the compilation of a single method without executing it. Note that the VM still needs to be initialized and some static class initializers will still be compiled (and traced) and executed.
Example: jato -Xtrace:jit -Xtrace:method 'java/nio/charset/CharsetEncoder.<init>(Ljava/nio/charset/Charset;FF[B)V' Signed-off-by: Vegard Nossum <vegard.nos...@gmail.com> --- vm/jato.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 115 insertions(+), 33 deletions(-) diff --git a/vm/jato.c b/vm/jato.c index 37ccd66..d8ebe78 100644 --- a/vm/jato.c +++ b/vm/jato.c @@ -676,11 +676,25 @@ static void handle_classpath(const char *arg) classloader_add_to_classpath(arg); } +enum operation { + OPERATION_MAIN_CLASS, + OPERATION_JAR_FILE, + OPERATION_METHOD_TRACE, +}; + +static enum operation operation = OPERATION_MAIN_CLASS; + static char *classname; static struct vm_jar *jar_file; +static char *method_trace_class_name; +static char *method_trace_method_name; +static char *method_trace_method_type; + static void handle_jar(const char *arg) { + operation = OPERATION_JAR_FILE; + /* Can't specify more than one jar file */ if (jar_file) usage(stderr, EXIT_FAILURE); @@ -714,6 +728,30 @@ static void handle_perf(void) perf_enabled = true; } +/* @arg must be in the format package/name/Class.method(Lsignature;)V */ +static void handle_trace_method(const char *arg) +{ + char *next; + + operation = OPERATION_METHOD_TRACE; + + next = strchr(arg, '.'); + if (!next) + usage(stderr, EXIT_FAILURE); + + method_trace_class_name = strndup(arg, next - arg); + + arg = next + 1; + next = strchr(arg, '('); + if (!next) + usage(stderr, EXIT_FAILURE); + + method_trace_method_name = strndup(arg, next - arg); + + arg = next; + method_trace_method_type = strdup(arg); +} + static void handle_trace_asm(void) { opt_trace_method = true; @@ -844,6 +882,8 @@ const struct option options[] = { DEFINE_OPTION("Xperf", handle_perf), + DEFINE_OPTION_ARG("Xtrace:method", handle_trace_method), + DEFINE_OPTION("Xtrace:asm", handle_trace_asm), DEFINE_OPTION("Xtrace:bytecode", handle_trace_bytecode), DEFINE_OPTION("Xtrace:bytecode-offset", handle_trace_bytecode_offset), @@ -903,9 +943,8 @@ static void parse_options(int argc, char *argv[]) opt->handler.func_arg(argv[++optind]); } - if (optind < argc) { - /* Can't specify both a jar and a class file */ - if (jar_file) + if (operation == OPERATION_MAIN_CLASS) { + if (optind >= argc) usage(stderr, EXIT_FAILURE); classname = argv[optind++]; @@ -914,10 +953,68 @@ static void parse_options(int argc, char *argv[]) /* Should be no more options after this */ if (optind < argc) usage(stderr, EXIT_FAILURE); +} - /* Can't specify neither a jar and a class file */ - if (!classname) - usage(stderr, EXIT_FAILURE); +static int +do_main_class(void) +{ + struct vm_class *vmc = classloader_load(classname); + if (!vmc) { + fprintf(stderr, "error: %s: could not load\n", classname); + return -1; + } + + if (vm_class_ensure_init(vmc)) { + fprintf(stderr, "error: %s: couldn't initialize\n", classname); + return -1; + } + + struct vm_method *vmm = vm_class_get_method_recursive(vmc, + "main", "([Ljava/lang/String;)V"); + if (!vmm) { + fprintf(stderr, "error: %s: no main method\n", classname); + return -1; + } + + if (!vm_method_is_static(vmm)) { + fprintf(stderr, "error: %s: main method not static\n", + classname); + return -1; + } + + void (*main_method_trampoline)(void) + = vm_method_trampoline_ptr(vmm); + main_method_trampoline(); + + return 0; +} + +static int +do_jar_file(void) +{ + /* XXX: This stub should be expanded in the future; see comment in + * handle_jar(). */ + return do_main_class(); +} + +static int +do_method_trace(void) +{ + struct vm_class *vmc = classloader_load(method_trace_class_name); + if (!vmc) { + NOT_IMPLEMENTED; + return -1; + } + + struct vm_method *vmm = vm_class_get_method_recursive(vmc, + method_trace_method_name, method_trace_method_type); + if (!vmm) { + NOT_IMPLEMENTED; + return -1; + } + + compile(vmm->compilation_unit); + return 0; } int @@ -933,9 +1030,9 @@ main(int argc, char *argv[]) setvbuf(stderr, NULL, _IONBF, 0); #endif - init_system_properties(); parse_options(argc, argv); + init_system_properties(); init_vm_objects(); jit_text_init(); @@ -971,34 +1068,19 @@ main(int argc, char *argv[]) goto out_check_exception; } - struct vm_class *vmc = classloader_load(classname); - if (!vmc) { - fprintf(stderr, "error: %s: could not load\n", classname); - goto out; + switch (operation) { + case OPERATION_MAIN_CLASS: + do_main_class(); + break; + case OPERATION_JAR_FILE: + do_jar_file(); + break; + case OPERATION_METHOD_TRACE: + do_method_trace(); + exit(EXIT_SUCCESS); + break; } - if (vm_class_ensure_init(vmc)) { - fprintf(stderr, "error: %s: couldn't initialize\n", classname); - goto out_check_exception; - } - - struct vm_method *vmm = vm_class_get_method_recursive(vmc, - "main", "([Ljava/lang/String;)V"); - if (!vmm) { - fprintf(stderr, "error: %s: no main method\n", classname); - goto out; - } - - if (!vm_method_is_static(vmm)) { - fprintf(stderr, "error: %s: main method not static\n", - classname); - goto out; - } - - void (*main_method_trampoline)(void) - = vm_method_trampoline_ptr(vmm); - main_method_trampoline(); - out_check_exception: if (exception_occurred()) { vm_print_exception(exception_occurred()); -- 1.6.0.6 ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel