From 2a83cc7ccda4711c3c03ee8b38ff06ef0b9ce7a9 Mon Sep 17 00:00:00 2001 From: edwin Date: Fri, 29 Sep 2006 12:46:15 +0000 Subject: [PATCH] Merged r5573, r5574, r5577, r5578, and r5579 from trunk. * src/cacao/cacao.c (vm/vm.h): Added. * src/cacao/Makefile.am [!ENABLE_LIBJVM] (CACAO_LIB): Link libjvm.la. * src/vm/jit/powerpc/darwin/md-asm.h (md_codegen_get_pv_from_pc): Added stub define. * src/vm/jit/powerpc/asmpart.S (L_md_codegen_get_pv_from_pc$stub): Added. * src/cacaoh/cacaoh.c (cacaoh_options_prepare): Set nOptions, this was deleted accidentally. * src/vm/vm.c (vm_create): Added installation of exit handler. (vm_run): New function. (vm_get_mainclass_from_jar): Likewise. (vm_compile_all): Likewise. (vm_compile_method): Likewise. * src/vm/vm.h (vm_run): New function. * src/vm/options.c (options_prepare): Removed. * src/vm/options.h (options_prepare): Likewise. * src/cacao/cacao.c (getmainclassnamefromjar): Removed. (main): Moved most stuff to vm-functions and load libjvm with dlopen and resolve symbols for ENABLE_LIBJVM. (cacao_options_prepare): New function. * src/cacao/Makefile.am (CACAO_LIBS): New variable. (cacao_LDADD): Use CACAO_LIBS. * src/native/native.c (native_init): Set mainhandle to libjvm for ENABLE_LIBJVM. * src/cacaoh/cacaoh.c (cacaoh_prepare_options): New function. * src/native/jni.c (JNI_CreateJavaVM): Renamed jvm to vm. --HG-- branch : unified_variables --- src/cacao/Makefile.am | 13 +- src/cacao/cacao.c | 432 +++++------------------------ src/cacaoh/cacaoh.c | 40 ++- src/native/jni.c | 14 +- src/native/native.c | 24 +- src/vm/jit/powerpc/asmpart.S | 22 +- src/vm/jit/powerpc/darwin/md-asm.h | 5 +- src/vm/options.c | 27 +- src/vm/options.h | 3 +- src/vm/vm.c | 386 +++++++++++++++++++++++++- src/vm/vm.h | 1 + 11 files changed, 541 insertions(+), 426 deletions(-) diff --git a/src/cacao/Makefile.am b/src/cacao/Makefile.am index 8b96e31ee..a35d863b3 100644 --- a/src/cacao/Makefile.am +++ b/src/cacao/Makefile.am @@ -28,7 +28,7 @@ ## ## Changes: ## -## $Id: Makefile.am 4970 2006-05-29 14:31:12Z twisti $ +## $Id: Makefile.am 5579 2006-09-29 11:37:12Z twisti $ ## Process this file with automake to produce Makefile.in @@ -60,12 +60,17 @@ libjvm_la_LDFLAGS = \ cacao_LDFLAGS += \ -export-dynamic + +CACAO_LIBS = else noinst_LTLIBRARIES = \ libjvm.la cacao_LDFLAGS += \ -export-dynamic + +CACAO_LIBS = \ + libjvm.la endif if WITH_STATIC_CLASSPATH @@ -80,6 +85,9 @@ CLASSPATH_LIBS = \ $(CLASSPATH_LIBDIR)/classpath/libjavalang.a \ $(CLASSPATH_LIBDIR)/classpath/libjavalangreflect.a +CACAO_LIBS += \ + $(CLASSPATH_LIBS) + #if USE_GTK_PEER #cacao_CFLAGS = \ # $(GTK_CFLAGS) $(CAIRO_CFLAGS) $(PANGOFT2_CFLAGS) \ @@ -116,8 +124,7 @@ cacao_SOURCES = \ cacao.c cacao_LDADD = \ - libjvm.la \ - $(CLASSPATH_LIBS) + $(CACAO_LIBS) cacao_DEPENDENCIES = \ $(cacao_LDADD) diff --git a/src/cacao/cacao.c b/src/cacao/cacao.c index 7bc89224e..fe1df0adc 100644 --- a/src/cacao/cacao.c +++ b/src/cacao/cacao.c @@ -31,7 +31,7 @@ Philipp Tomsich Christian Thalinger - $Id: cacao.c 5195 2006-07-31 15:26:10Z twisti $ + $Id: cacao.c 5579 2006-09-29 11:37:12Z twisti $ */ @@ -39,147 +39,29 @@ #include "config.h" #include + +#if defined(ENABLE_LIBJVM) +# include +#endif + #include #include #include "vm/types.h" #include "native/jni.h" -#include "native/include/java_lang_String.h" #if defined(ENABLE_JVMTI) -#include "native/jvmti/jvmti.h" -#include "native/jvmti/cacaodbg.h" - -#if defined(ENABLE_THREADS) -#include -#endif +# include "native/jvmti/jvmti.h" +# include "native/jvmti/cacaodbg.h" #endif -#include "toolbox/logging.h" -#include "vm/classcache.h" -#include "vm/exceptions.h" -#include "vm/global.h" -#include "vm/loader.h" -#include "vm/options.h" -#include "vm/statistics.h" -#include "vm/stringlocal.h" -#include "vm/suck.h" #include "vm/vm.h" -#include "vm/jit/asmpart.h" -#include "vm/jit/jit.h" - -#ifdef TYPEINFO_DEBUG_TEST -#include "vm/jit/verify/typeinfo.h" -#endif -#ifdef TYPECHECK_STATISTICS -void typecheck_print_statistics(FILE *file); -#endif -/* getmainclassfromjar ********************************************************* - - Gets the name of the main class form a JAR's manifest file. - -*******************************************************************************/ - -static char *getmainclassnamefromjar(char *mainstring) -{ - classinfo *c; - java_objectheader *o; - methodinfo *m; - java_lang_String *s; - - c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile")); - - if (!c) - throw_main_exception_exit(); - - /* create JarFile object */ - - o = builtin_new(c); - - if (!o) - throw_main_exception_exit(); - - - m = class_resolveclassmethod(c, - utf_init, - utf_java_lang_String__void, - class_java_lang_Object, - true); - - if (!m) - throw_main_exception_exit(); - - s = javastring_new_from_ascii(mainstring); - - (void) vm_call_method(m, o, s); - - if (*exceptionptr) - throw_main_exception_exit(); - - /* get manifest object */ - - m = class_resolveclassmethod(c, - utf_new_char("getManifest"), - utf_new_char("()Ljava/util/jar/Manifest;"), - class_java_lang_Object, - true); - - if (!m) - throw_main_exception_exit(); - - o = vm_call_method(m, o); - - if (o == NULL) { - fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring); - vm_exit(1); - } - - - /* get Main Attributes */ - - m = class_resolveclassmethod(o->vftbl->class, - utf_new_char("getMainAttributes"), - utf_new_char("()Ljava/util/jar/Attributes;"), - class_java_lang_Object, - true); - - if (!m) - throw_main_exception_exit(); - - o = vm_call_method(m, o); - - if (o == NULL) { - fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring); - vm_exit(1); - } - - - /* get property Main-Class */ - - m = class_resolveclassmethod(o->vftbl->class, - utf_new_char("getValue"), - utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"), - class_java_lang_Object, - true); - - if (!m) - throw_main_exception_exit(); - - s = javastring_new_from_ascii("Main-Class"); - - o = vm_call_method(m, o, s); - - if (!o) - throw_main_exception_exit(); - - return javastring_tochar(o); -} - -void exit_handler(void); +/* forward declarations *******************************************************/ +static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv); /* main ************************************************************************ @@ -190,274 +72,96 @@ void exit_handler(void); int main(int argc, char **argv) { - s4 i; - - /* local variables ********************************************************/ +#if defined(ENABLE_LIBJVM) + /* Variables for JNI_CreateJavaVM dlopen call. */ + lt_dlhandle libjvm_handle; + lt_ptr libjvm_createvm; + lt_ptr libjvm_vm_run; + + s4 (*JNI_CreateJavaVM)(JavaVM **, void **, void *); + void (*vm_run)(JavaVM *, JavaVMInitArgs *); +#endif + JavaVM *vm; /* denotes a Java VM */ + JNIEnv *env; JavaVMInitArgs *vm_args; - JavaVM *jvm; /* denotes a Java VM */ - - if (atexit(vm_exit_handler)) - throw_cacao_exception_exit(string_java_lang_InternalError, - "Unable to register exit_handler"); - - - /**************************** Program start *****************************/ - - if (opt_verbose) - log_text("CACAO started -------------------------------------------------------"); /* prepare the options */ - vm_args = options_prepare(argc, argv); + vm_args = cacao_options_prepare(argc, argv); /* load and initialize a Java VM, return a JNI interface pointer in env */ - JNI_CreateJavaVM(&jvm, (void *) &_Jv_env, vm_args); - -#if defined(ENABLE_JVMTI) - pthread_mutex_init(&dbgcomlock,NULL); - if (jvmti) jvmti_set_phase(JVMTI_PHASE_START); -#endif - - /* do we have a main class? */ - - if (mainstring == NULL) - usage(); - - - /* start worker routines **************************************************/ - - if (opt_run == true) { - utf *mainutf; - classinfo *mainclass; - methodinfo *m; - java_objectarray *oa; - s4 oalength; - java_lang_String *s; - s4 status; - - /* set return value to OK */ - - status = 0; - - if (opt_jar == true) { - /* open jar file with java.util.jar.JarFile */ - mainstring = getmainclassnamefromjar(mainstring); - } - - /* load the main class */ - - mainutf = utf_new_char(mainstring); - - if (!(mainclass = load_class_from_sysloader(mainutf))) - throw_main_exception_exit(); - - /* error loading class, clear exceptionptr for new exception */ - - if (*exceptionptr || !mainclass) { -/* *exceptionptr = NULL; */ - -/* *exceptionptr = */ -/* new_exception_message(string_java_lang_NoClassDefFoundError, */ -/* mainstring); */ - throw_main_exception_exit(); - } - - if (!link_class(mainclass)) - throw_main_exception_exit(); - - /* find the `main' method of the main class */ - - m = class_resolveclassmethod(mainclass, - utf_new_char("main"), - utf_new_char("([Ljava/lang/String;)V"), - class_java_lang_Object, - false); - - if (*exceptionptr) { - throw_main_exception_exit(); - } - - /* there is no main method or it isn't static */ - - if (!m || !(m->flags & ACC_STATIC)) { - *exceptionptr = NULL; - - *exceptionptr = - new_exception_message(string_java_lang_NoSuchMethodError, - "main"); - throw_main_exception_exit(); - } +#if defined(ENABLE_LIBJVM) + if (lt_dlinit()) { + fprintf(stderr, "lt_dlinit failed: %s\n", lt_dlerror()); + abort(); + } - /* build argument array */ + if (!(libjvm_handle = lt_dlopenext(CACAO_LIBDIR"/libjvm"))) { + fprintf(stderr, "lt_dlopenext failed: %s\n", lt_dlerror()); + abort(); + } - oalength = vm_args->nOptions - opt_index; + if (!(libjvm_createvm = lt_dlsym(libjvm_handle, "JNI_CreateJavaVM"))) { + fprintf(stderr, "lt_dlsym failed: %s\n", lt_dlerror()); + abort(); + } - oa = builtin_anewarray(oalength, class_java_lang_String); + JNI_CreateJavaVM = + (s4 (*)(JavaVM **, void **, void *)) (ptrint) libjvm_createvm; +#endif - for (i = 0; i < oalength; i++) { - s = javastring_new(utf_new_char(vm_args->options[opt_index + i].optionString)); - oa->data[i] = (java_objectheader *) s; - } + /* create the Java VM */ -#ifdef TYPEINFO_DEBUG_TEST - /* test the typeinfo system */ - typeinfo_test(); -#endif - /*class_showmethods(currentThread->group->header.vftbl->class); */ + JNI_CreateJavaVM(&vm, (void *) &env, vm_args); #if defined(ENABLE_JVMTI) - jvmti_set_phase(JVMTI_PHASE_LIVE); + pthread_mutex_init(&dbgcomlock,NULL); + if (jvmti) jvmti_set_phase(JVMTI_PHASE_START); #endif - /* increase total started thread count */ - - _Jv_jvm->total_started_thread_count++; - - /* start the main thread */ - - (void) vm_call_method(m, NULL, oa); - - /* exception occurred? */ - - if (*exceptionptr) { - throw_main_exception(); - status = 1; - } - - /* unload the JavaVM */ - - vm_destroy(jvm); - - /* and exit */ - - vm_exit(status); +#if defined(ENABLE_LIBJVM) + if (!(libjvm_vm_run = lt_dlsym(libjvm_handle, "vm_run"))) { + fprintf(stderr, "lt_dlsym failed: %s\n", lt_dlerror()); + abort(); } + vm_run = (void (*)(JavaVM *, JavaVMInitArgs *)) (ptrint) libjvm_vm_run; +#endif - /* If requested, compile all methods. *************************************/ - -#if !defined(NDEBUG) - if (compileall) { - classinfo *c; - methodinfo *m; - u4 slot; - s4 i; - classcache_name_entry *nmen; - classcache_class_entry *clsen; - - /* create all classes found in the bootclasspath */ - /* XXX currently only works with zip/jar's */ - - loader_load_all_classes(); - - /* link all classes */ - - for (slot = 0; slot < hashtable_classcache.size; slot++) { - nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot]; - - for (; nmen; nmen = nmen->hashlink) { - /* iterate over all class entries */ - - for (clsen = nmen->classes; clsen; clsen = clsen->next) { - c = clsen->classobj; - - if (!c) - continue; - - if (!(c->state & CLASS_LINKED)) { - if (!link_class(c)) { - fprintf(stderr, "Error linking: "); - utf_fprint_printable_ascii_classname(stderr, c->name); - fprintf(stderr, "\n"); + /* run the VM */ - /* print out exception and cause */ + vm_run(vm, vm_args); - exceptions_print_exception(*exceptionptr); + /* keep compiler happy */ - /* goto next class */ + return 0; +} - continue; - } - } - /* compile all class methods */ +/* cacao_options_prepare ******************************************************* - for (i = 0; i < c->methodscount; i++) { - m = &(c->methods[i]); + Prepare the JavaVMInitArgs. - if (m->jcode) { - if (!jit_compile(m)) { - fprintf(stderr, "Error compiling: "); - utf_fprint_printable_ascii_classname(stderr, c->name); - fprintf(stderr, "."); - utf_fprint_printable_ascii(stderr, m->name); - utf_fprint_printable_ascii(stderr, m->descriptor); - fprintf(stderr, "\n"); +*******************************************************************************/ - /* print out exception and cause */ +static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv) +{ + JavaVMInitArgs *vm_args; + s4 i; - exceptions_print_exception(*exceptionptr); - } - } - } - } - } - } - } -#endif /* !defined(NDEBUG) */ - - - /* If requested, compile a specific method. *******************************/ - -#if !defined(NDEBUG) - if (opt_method != NULL) { - methodinfo *m; - - /* create, load and link the main class */ - - if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring)))) - throw_main_exception_exit(); - - if (!link_class(mainclass)) - throw_main_exception_exit(); - - if (opt_signature != NULL) { - m = class_resolveclassmethod(mainclass, - utf_new_char(opt_method), - utf_new_char(opt_signature), - mainclass, - false); - } else { - m = class_resolveclassmethod(mainclass, - utf_new_char(opt_method), - NULL, - mainclass, - false); - } - - if (!m) { - char message[MAXLOGTEXT]; - sprintf(message, "%s%s", opt_method, - opt_signature ? opt_signature : ""); - - *exceptionptr = - new_exception_message(string_java_lang_NoSuchMethodException, - message); - - throw_main_exception_exit(); - } - - jit_compile(m); - } + vm_args = malloc(sizeof(JavaVMInitArgs)); - vm_shutdown(0); -#endif /* !defined(NDEBUG) */ + vm_args->version = JNI_VERSION_1_2; + vm_args->nOptions = argc - 1; + vm_args->options = malloc(sizeof(JavaVMOption) * argc); + vm_args->ignoreUnrecognized = JNI_FALSE; - /* keep compiler happy */ + for (i = 1; i < argc; i++) + vm_args->options[i - 1].optionString = argv[i]; - return 0; + return vm_args; } diff --git a/src/cacaoh/cacaoh.c b/src/cacaoh/cacaoh.c index 9a3e24240..03d4994a7 100644 --- a/src/cacaoh/cacaoh.c +++ b/src/cacaoh/cacaoh.c @@ -30,7 +30,7 @@ Philipp Tomsich Christian Thalinger - $Id: cacaoh.c 5013 2006-06-06 11:22:56Z twisti $ + $Id: cacaoh.c 5577 2006-09-29 10:38:58Z twisti $ */ @@ -147,6 +147,11 @@ static void version(void) } +/* forward declarations *******************************************************/ + +static JavaVMInitArgs *cacaoh_options_prepare(int argc, char **argv); + + /* main ************************************************************************ Main program. @@ -185,8 +190,8 @@ int main(int argc, char **argv) if (cp) { bootclasspath = MNEW(char, strlen(cp) + strlen("0")); strcpy(bootclasspath, cp); - - } else { + } + else { cplen = strlen(CACAO_VM_ZIP) + strlen(":") + strlen(CLASSPATH_GLIBJ_ZIP) + @@ -206,8 +211,8 @@ int main(int argc, char **argv) if (cp) { classpath = MNEW(char, strlen(cp) + strlen("0")); strcat(classpath, cp); - - } else { + } + else { classpath = MNEW(char, strlen(".") + strlen("0")); strcpy(classpath, "."); } @@ -224,7 +229,7 @@ int main(int argc, char **argv) /* parse the options ******************************************************/ - vm_args = options_prepare(argc, argv); + vm_args = cacaoh_options_prepare(argc, argv); while ((opt = options_get(opts, vm_args)) != OPT_DONE) { switch (opt) { @@ -371,6 +376,29 @@ int main(int argc, char **argv) } +/* cacaoh_options_prepare ****************************************************** + + Prepare the JavaVMInitArgs. + +*******************************************************************************/ + +static JavaVMInitArgs *cacaoh_options_prepare(int argc, char **argv) +{ + JavaVMInitArgs *vm_args; + s4 i; + + vm_args = NEW(JavaVMInitArgs); + + vm_args->nOptions = argc - 1; + vm_args->options = MNEW(JavaVMOption, argc); + + for (i = 1; i < argc; i++) + vm_args->options[i - 1].optionString = argv[i]; + + return vm_args; +} + + /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where diff --git a/src/native/jni.c b/src/native/jni.c index c004758a4..84f2566c9 100644 --- a/src/native/jni.c +++ b/src/native/jni.c @@ -32,7 +32,7 @@ Christian Thalinger Edwin Steiner - $Id: jni.c 5572 2006-09-28 20:38:28Z edwin $ + $Id: jni.c 5573 2006-09-28 20:39:40Z twisti $ */ @@ -5805,7 +5805,7 @@ jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args) { JavaVMInitArgs *_vm_args; _Jv_JNIEnv *env; - _Jv_JavaVM *jvm; + _Jv_JavaVM *vm; localref_table *lrt; /* get the arguments for the new JVM */ @@ -5823,13 +5823,13 @@ jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args) /* create and fill a JavaVM structure */ - jvm = NEW(_Jv_JavaVM); - jvm->functions = &_Jv_JNIInvokeInterface; + vm = NEW(_Jv_JavaVM); + vm->functions = &_Jv_JNIInvokeInterface; /* XXX Set the global variable. Maybe we should do that differently. */ /* XXX JVMTI Agents needs a JavaVM */ - _Jv_jvm = jvm; + _Jv_jvm = vm; /* actually create the JVM */ @@ -5837,7 +5837,7 @@ jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args) /* release allocated memory */ FREE(env, _Jv_JNIEnv); - FREE(jvm, _Jv_JavaVM); + FREE(vm, _Jv_JavaVM); return -1; } @@ -5859,7 +5859,7 @@ jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args) /* now return the values */ - *p_vm = (JavaVM *) jvm; + *p_vm = (JavaVM *) vm; *p_env = (void *) env; return 0; diff --git a/src/native/native.c b/src/native/native.c index 834d33af6..205eb3c82 100644 --- a/src/native/native.c +++ b/src/native/native.c @@ -30,7 +30,7 @@ Changes: Christian Thalinger - $Id: native.c 5567 2006-09-28 20:20:18Z edwin $ + $Id: native.c 5574 2006-09-28 20:47:58Z twisti $ */ @@ -328,9 +328,9 @@ static lt_dlhandle mainhandle; #endif -/* native_loadclasses ********************************************************** +/* native_init ***************************************************************** - Load classes required for native methods. + Initializes the native subsystem. *******************************************************************************/ @@ -339,17 +339,19 @@ bool native_init(void) #if !defined(WITH_STATIC_CLASSPATH) /* initialize libltdl */ - if (lt_dlinit()) { - /* XXX how can we throw an exception here? */ - log_text(lt_dlerror()); + if (lt_dlinit()) + vm_abort("lt_dlinit failed: %s\n", lt_dlerror()); - return false; - } - - /* get the handle for the main program */ + /* Get the handle for the main program or for the libjvm.so, + depends on the configuration. */ +# if defined(ENABLE_LIBJVM) + if (!(mainhandle = lt_dlopenext(CACAO_LIBDIR"/libjvm"))) + vm_abort("lt_dlopenext failed: %s\n", lt_dlerror()); +# else if (!(mainhandle = lt_dlopen(NULL))) - return false; + vm_abort("lt_dlopen failed: %s\n", lt_dlerror()); +# endif /* initialize library hashtable, 10 entries should be enough */ diff --git a/src/vm/jit/powerpc/asmpart.S b/src/vm/jit/powerpc/asmpart.S index e53423d6c..222d27ca1 100644 --- a/src/vm/jit/powerpc/asmpart.S +++ b/src/vm/jit/powerpc/asmpart.S @@ -31,7 +31,7 @@ Changes: Christian Thalinger Edwin Steiner - $Id: asmpart.S 5287 2006-09-04 14:21:11Z twisti $ + $Id: asmpart.S 5578 2006-09-29 11:35:04Z twisti $ */ @@ -1411,6 +1411,26 @@ L_builtin_throw_exception$lazy_ptr: .long dyld_stub_binding_helper +.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align 2 +L_md_codegen_get_pv_from_pc$stub: + .indirect_symbol _md_codegen_get_pv_from_pc + mflr r0 + bcl 20,31,L00$_md_codegen_get_pv_from_pc +L00$_md_codegen_get_pv_from_pc: + mflr r11 + addis r11,r11,ha16(L_md_codegen_get_pv_from_pc$lazy_ptr - L00$_md_codegen_get_pv_from_pc) + mtlr r0 + lwzu r12,lo16(L_md_codegen_get_pv_from_pc$lazy_ptr - L00$_md_codegen_get_pv_from_pc)(r11) + mtctr r12 + bctr +.data +.lazy_symbol_pointer +L_md_codegen_get_pv_from_pc$lazy_ptr: + .indirect_symbol _md_codegen_get_pv_from_pc + .long dyld_stub_binding_helper + + .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 .align 2 L_exceptions_handle_exception$stub: diff --git a/src/vm/jit/powerpc/darwin/md-asm.h b/src/vm/jit/powerpc/darwin/md-asm.h index db318f4a3..ae21a7111 100644 --- a/src/vm/jit/powerpc/darwin/md-asm.h +++ b/src/vm/jit/powerpc/darwin/md-asm.h @@ -28,7 +28,7 @@ Changes: - $Id: md-asm.h 5254 2006-08-21 14:52:20Z twisti $ + $Id: md-asm.h 5578 2006-09-29 11:35:04Z twisti $ */ @@ -255,7 +255,10 @@ L_exceptions_get_and_clear_exception$stub #define builtin_throw_exception L_builtin_throw_exception$stub + +#define md_codegen_get_pv_from_pc L_md_codegen_get_pv_from_pc$stub #define exceptions_handle_exception L_exceptions_handle_exception$stub + #define jit_asm_compile L_jit_asm_compile$stub #define exceptions_asm_new_abstractmethoderror \ diff --git a/src/vm/options.c b/src/vm/options.c index eba1fe7f0..96df759f3 100644 --- a/src/vm/options.c +++ b/src/vm/options.c @@ -28,7 +28,7 @@ Changes: - $Id: options.c 5258 2006-08-22 09:02:25Z tbfg $ + $Id: options.c 5574 2006-09-28 20:47:58Z twisti $ */ @@ -220,31 +220,6 @@ s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args) } -/* options_prepare ************************************************************* - - Prepare the JavaVMInitArgs. - -*******************************************************************************/ - -JavaVMInitArgs *options_prepare(int argc, char **argv) -{ - JavaVMInitArgs *vm_args; - s4 i; - - vm_args = NEW(JavaVMInitArgs); - - vm_args->version = JNI_VERSION_1_2; - vm_args->nOptions = argc - 1; - vm_args->options = MNEW(JavaVMOption, argc); - vm_args->ignoreUnrecognized = JNI_FALSE; - - for (i = 1; i < argc; i++) - vm_args->options[i - 1].optionString = argv[i]; - - return vm_args; -} - - /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where diff --git a/src/vm/options.h b/src/vm/options.h index 376bb3b61..662645e48 100644 --- a/src/vm/options.h +++ b/src/vm/options.h @@ -28,7 +28,7 @@ Changes: - $Id: options.h 5258 2006-08-22 09:02:25Z tbfg $ + $Id: options.h 5574 2006-09-28 20:47:58Z twisti $ */ @@ -164,7 +164,6 @@ extern bool vm_debug; /* function prototypes ********************************************************/ s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args); -JavaVMInitArgs *options_prepare(int argc, char **argv); #endif /* _OPTIONS_H */ diff --git a/src/vm/vm.c b/src/vm/vm.c index 3b98ce353..98a9fef7b 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -36,6 +36,7 @@ #include "config.h" #include +#include #include #include "vm/types.h" @@ -563,6 +564,13 @@ static void fullversion(void) } +/* forward declarations *******************************************************/ + +static char *vm_get_mainclass_from_jar(char *mainstring); +static void vm_compile_all(void); +static void vm_compile_method(void); + + /* vm_create ******************************************************************* Creates a JVM. Called by JNI_CreateJavaVM. @@ -602,6 +610,12 @@ bool vm_create(JavaVMInitArgs *vm_args) if (vms > 0) return false; + if (atexit(vm_exit_handler)) + vm_abort("atexit failed: %s\n", strerror(errno)); + + if (opt_verbose) + log_text("CACAO started -------------------------------------------------------"); + /* set the VM starttime */ _Jv_jvm->starttime = builtin_currenttimemillis(); @@ -639,8 +653,8 @@ bool vm_create(JavaVMInitArgs *vm_args) if (cp) { classpath = MNEW(char, strlen(cp) + strlen("0")); strcat(classpath, cp); - - } else { + } + else { classpath = MNEW(char, strlen(".") + strlen("0")); strcpy(classpath, "."); } @@ -674,7 +688,6 @@ bool vm_create(JavaVMInitArgs *vm_args) properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed"); - /* iterate over all passed options */ while ((opt = options_get(opts, vm_args)) != OPT_DONE) { @@ -1175,8 +1188,8 @@ bool vm_create(JavaVMInitArgs *vm_args) classpath = MNEW(char, strlen(mainstring) + strlen("0")); strcpy(classpath, mainstring); - - } else { + } + else { /* replace .'s with /'s in classname */ for (i = strlen(mainstring) - 1; i >= 0; i--) @@ -1376,6 +1389,138 @@ bool vm_create(JavaVMInitArgs *vm_args) } +/* vm_run ********************************************************************** + + Runs the main-method of the passed class. + +*******************************************************************************/ + +void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args) +{ + utf *mainutf; + classinfo *mainclass; + methodinfo *m; + java_objectarray *oa; + s4 oalength; + utf *u; + java_lang_String *s; + s4 status; + s4 i; + + if (compileall) { + vm_compile_all(); + return; + } + + if (opt_method != NULL) { + vm_compile_method(); + return; + } + + /* should we run the main-method? */ + + if (mainstring == NULL) + usage(); + + /* set return value to OK */ + + status = 0; + + if (opt_jar == true) + /* open jar file with java.util.jar.JarFile */ + mainstring = vm_get_mainclass_from_jar(mainstring); + + /* load the main class */ + + mainutf = utf_new_char(mainstring); + + if (!(mainclass = load_class_from_sysloader(mainutf))) + throw_main_exception_exit(); + + /* error loading class, clear exceptionptr for new exception */ + + if (*exceptionptr || !mainclass) { + /* *exceptionptr = NULL; */ + + /* *exceptionptr = */ + /* new_exception_message(string_java_lang_NoClassDefFoundError, */ + /* mainstring); */ + throw_main_exception_exit(); + } + + if (!link_class(mainclass)) + throw_main_exception_exit(); + + /* find the `main' method of the main class */ + + m = class_resolveclassmethod(mainclass, + utf_new_char("main"), + utf_new_char("([Ljava/lang/String;)V"), + class_java_lang_Object, + false); + + if (*exceptionptr) { + throw_main_exception_exit(); + } + + /* there is no main method or it isn't static */ + + if ((m == NULL) || !(m->flags & ACC_STATIC)) { + *exceptionptr = NULL; + + *exceptionptr = + new_exception_message(string_java_lang_NoSuchMethodError, "main"); + throw_main_exception_exit(); + } + + /* build argument array */ + + oalength = vm_args->nOptions - opt_index; + + oa = builtin_anewarray(oalength, class_java_lang_String); + + for (i = 0; i < oalength; i++) { + u = utf_new_char(vm_args->options[opt_index + i].optionString); + s = javastring_new(u); + + oa->data[i] = (java_objectheader *) s; + } + +#ifdef TYPEINFO_DEBUG_TEST + /* test the typeinfo system */ + typeinfo_test(); +#endif + /*class_showmethods(currentThread->group->header.vftbl->class); */ + +#if defined(ENABLE_JVMTI) + jvmti_set_phase(JVMTI_PHASE_LIVE); +#endif + + /* increase total started thread count */ + + _Jv_jvm->total_started_thread_count++; + + /* start the main thread */ + + (void) vm_call_method(m, NULL, oa); + + /* exception occurred? */ + + if (*exceptionptr) { + throw_main_exception(); + status = 1; + } + + /* unload the JavaVM */ + + vm_destroy(vm); + + /* and exit */ + + vm_exit(status); +} + + /* vm_destroy ****************************************************************** Unloads a Java VM and reclaims its resources. @@ -1566,6 +1711,237 @@ void vm_abort(const char *text, ...) } +/* vm_get_mainclass_from_jar *************************************************** + + Gets the name of the main class from a JAR's manifest file. + +*******************************************************************************/ + +static char *vm_get_mainclass_from_jar(char *mainstring) +{ + classinfo *c; + java_objectheader *o; + methodinfo *m; + java_lang_String *s; + + c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile")); + + if (c == NULL) + throw_main_exception_exit(); + + /* create JarFile object */ + + o = builtin_new(c); + + if (o == NULL) + throw_main_exception_exit(); + + + m = class_resolveclassmethod(c, + utf_init, + utf_java_lang_String__void, + class_java_lang_Object, + true); + + if (m == NULL) + throw_main_exception_exit(); + + s = javastring_new_from_ascii(mainstring); + + (void) vm_call_method(m, o, s); + + if (*exceptionptr) + throw_main_exception_exit(); + + /* get manifest object */ + + m = class_resolveclassmethod(c, + utf_new_char("getManifest"), + utf_new_char("()Ljava/util/jar/Manifest;"), + class_java_lang_Object, + true); + + if (m == NULL) + throw_main_exception_exit(); + + o = vm_call_method(m, o); + + if (o == NULL) { + fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring); + vm_exit(1); + } + + + /* get Main Attributes */ + + m = class_resolveclassmethod(o->vftbl->class, + utf_new_char("getMainAttributes"), + utf_new_char("()Ljava/util/jar/Attributes;"), + class_java_lang_Object, + true); + + if (m == NULL) + throw_main_exception_exit(); + + o = vm_call_method(m, o); + + if (o == NULL) { + fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring); + vm_exit(1); + } + + + /* get property Main-Class */ + + m = class_resolveclassmethod(o->vftbl->class, + utf_new_char("getValue"), + utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"), + class_java_lang_Object, + true); + + if (m == NULL) + throw_main_exception_exit(); + + s = javastring_new_from_ascii("Main-Class"); + + o = vm_call_method(m, o, s); + + if (o == NULL) + throw_main_exception_exit(); + + return javastring_tochar(o); +} + + +/* vm_compile_all ************************************************************** + + Compile all methods found in the bootclasspath. + +*******************************************************************************/ + +#if !defined(NDEBUG) +static void vm_compile_all(void) +{ + classinfo *c; + methodinfo *m; + u4 slot; + classcache_name_entry *nmen; + classcache_class_entry *clsen; + s4 i; + + /* create all classes found in the bootclasspath */ + /* XXX currently only works with zip/jar's */ + + loader_load_all_classes(); + + /* link all classes */ + + for (slot = 0; slot < hashtable_classcache.size; slot++) { + nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot]; + + for (; nmen; nmen = nmen->hashlink) { + /* iterate over all class entries */ + + for (clsen = nmen->classes; clsen; clsen = clsen->next) { + c = clsen->classobj; + + if (c == NULL) + continue; + + if (!(c->state & CLASS_LINKED)) { + if (!link_class(c)) { + fprintf(stderr, "Error linking: "); + utf_fprint_printable_ascii_classname(stderr, c->name); + fprintf(stderr, "\n"); + + /* print out exception and cause */ + + exceptions_print_exception(*exceptionptr); + + /* goto next class */ + + continue; + } + } + + /* compile all class methods */ + + for (i = 0; i < c->methodscount; i++) { + m = &(c->methods[i]); + + if (m->jcode != NULL) { + if (!jit_compile(m)) { + fprintf(stderr, "Error compiling: "); + utf_fprint_printable_ascii_classname(stderr, c->name); + fprintf(stderr, "."); + utf_fprint_printable_ascii(stderr, m->name); + utf_fprint_printable_ascii(stderr, m->descriptor); + fprintf(stderr, "\n"); + + /* print out exception and cause */ + + exceptions_print_exception(*exceptionptr); + } + } + } + } + } + } +} +#endif /* !defined(NDEBUG) */ + + +/* vm_compile_method *********************************************************** + + Compile a specific method. + +*******************************************************************************/ + +#if !defined(NDEBUG) +static void vm_compile_method(void) +{ + methodinfo *m; + + /* create, load and link the main class */ + + if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring)))) + throw_main_exception_exit(); + + if (!link_class(mainclass)) + throw_main_exception_exit(); + + if (opt_signature != NULL) { + m = class_resolveclassmethod(mainclass, + utf_new_char(opt_method), + utf_new_char(opt_signature), + mainclass, + false); + } + else { + m = class_resolveclassmethod(mainclass, + utf_new_char(opt_method), + NULL, + mainclass, + false); + } + + if (m == NULL) { + char message[MAXLOGTEXT]; + sprintf(message, "%s%s", opt_method, + opt_signature ? opt_signature : ""); + + *exceptionptr = + new_exception_message(string_java_lang_NoSuchMethodException, + message); + + throw_main_exception_exit(); + } + + jit_compile(m); +} +#endif /* !defined(NDEBUG) */ + + /* vm_vmargs_from_valist ******************************************************* XXX diff --git a/src/vm/vm.h b/src/vm/vm.h index bc3deb12c..d9f738dd9 100644 --- a/src/vm/vm.h +++ b/src/vm/vm.h @@ -84,6 +84,7 @@ struct vm_arg { void usage(void); bool vm_create(JavaVMInitArgs *vm_args); +void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args); s4 vm_destroy(JavaVM *vm); void vm_exit(s4 status); void vm_shutdown(s4 status); -- 2.25.1