X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Finitialize.c;h=1833a459eac3133cf6de1546582150160c025b84;hb=0aebab5e9ab8bb6e7ad59f26001f17c7ce9b7620;hp=1a12b0ba97fa562609f249e23247cb4ed842c529;hpb=f3b341d7558f51a2cf469315a4215185124f2faa;p=cacao.git diff --git a/src/vm/initialize.c b/src/vm/initialize.c index 1a12b0ba9..1833a459e 100644 --- a/src/vm/initialize.c +++ b/src/vm/initialize.c @@ -1,9 +1,9 @@ /* src/vm/initialize.c - static class initializer functions - Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates, - R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner, - C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger, - Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel, + C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, + E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, + J. Wenninger, Institut f. Computersprachen - TU Wien This file is part of CACAO. @@ -19,10 +19,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. - Contact: cacao@complang.tuwien.ac.at + Contact: cacao@cacaojvm.org Authors: Reinhard Grafl @@ -30,21 +30,27 @@ Andreas Krall Christian Thalinger - $Id: initialize.c 2197 2005-04-03 21:39:07Z twisti $ + $Id: initialize.c 4921 2006-05-15 14:24:36Z twisti $ */ +#include "config.h" + #include -#include "config.h" +#include "vm/types.h" + +#include "vm/global.h" +#include "vm/initialize.h" #include "vm/builtin.h" #include "vm/class.h" +#include "vm/loader.h" #include "vm/exceptions.h" -#include "vm/global.h" #include "vm/options.h" #include "vm/statistics.h" #include "vm/stringlocal.h" +#include "vm/vm.h" #include "vm/jit/asmpart.h" @@ -68,7 +74,7 @@ bool initialize_class(classinfo *c) if (!makeinitializations) return true; -#if defined(USE_THREADS) +#if defined(ENABLE_THREADS) /* enter a monitor on the class */ builtin_monitorenter((java_objectheader *) c); @@ -77,34 +83,48 @@ bool initialize_class(classinfo *c) /* maybe the class is already initalized or the current thread, which can pass the monitor, is currently initalizing this class */ - /* JOWENN: In future we need an additinal flag: initializationfailed, - since further access to the class should cause a NoClassDefFound, - if the static initializer failed once - */ + if (CLASS_IS_OR_ALMOST_INITIALIZED(c)) { +#if defined(ENABLE_THREADS) + builtin_monitorexit((java_objectheader *) c); +#endif - if (c->initialized || c->initializing) { -#if defined(USE_THREADS) + return true; + } + + /* if throw an Error before, the class was marked with an + error and we have to throw a NoClassDefFoundError */ + + if (c->state & CLASS_ERROR) { + *exceptionptr = new_noclassdeffounderror(c->name); + +#if defined(ENABLE_THREADS) builtin_monitorexit((java_objectheader *) c); #endif + /* ...but return true, this is ok (mauve test) */ + return true; } /* this initalizing run begins NOW */ - c->initializing = true; + + c->state |= CLASS_INITIALIZING; /* call the internal function */ + r = initialize_class_intern(c); /* if return value is not NULL everything was ok and the class is initialized */ + if (r) - c->initialized = true; + c->state |= CLASS_INITIALIZED; /* this initalizing run is done */ - c->initializing = false; -#if defined(USE_THREADS) + c->state &= ~CLASS_INITIALIZING; + +#if defined(ENABLE_THREADS) /* leave the monitor */ builtin_monitorexit((java_objectheader *) c); @@ -123,19 +143,16 @@ bool initialize_class(classinfo *c) static bool initialize_class_intern(classinfo *c) { - methodinfo *m; - s4 i; -#if defined(USE_THREADS) && !defined(NATIVE_THREADS) - int b; -#endif + methodinfo *m; + java_objectheader *xptr; /* maybe the class is not already linked */ - if (!c->linked) + if (!(c->state & CLASS_LINKED)) if (!link_class(c)) return false; -#if defined(STATISTICS) +#if defined(ENABLE_STATISTICS) if (opt_stat) count_class_inits++; #endif @@ -143,116 +160,76 @@ static bool initialize_class_intern(classinfo *c) /* initialize super class */ if (c->super.cls) { - if (!c->super.cls->initialized) { - if (initverbose) { - char logtext[MAXLOGTEXT]; - strcpy(logtext, "Initialize super class "); - utf_strcat_classname(logtext, c->super.cls->name); - strcat(logtext, " from "); - utf_strcat_classname(logtext, c->name); - log_text(logtext); - } + if (!(c->super.cls->state & CLASS_INITIALIZED)) { +#if !defined(NDEBUG) + if (initverbose) + log_message_class_message_class("Initialize super class ", + c->super.cls, + " from ", + c); +#endif if (!initialize_class(c->super.cls)) return false; } } - /* initialize interface classes */ - - for (i = 0; i < c->interfacescount; i++) { - if (!c->interfaces[i].cls->initialized) { - if (initverbose) { - char logtext[MAXLOGTEXT]; - strcpy(logtext, "Initialize interface class "); - utf_strcat_classname(logtext, c->interfaces[i].cls->name); - strcat(logtext, " from "); - utf_strcat_classname(logtext, c->name); - log_text(logtext); - } - - if (!initialize_class(c->interfaces[i].cls)) - return false; - } - } + /* interfaces implemented need not to be initialized (VM Spec 2.17.4) */ m = class_findmethod(c, utf_clinit, utf_void__void); if (!m) { - if (initverbose) { - char logtext[MAXLOGTEXT]; - strcpy(logtext, "Class "); - utf_strcat_classname(logtext, c->name); - strcat(logtext, " has no static class initializer"); - log_text(logtext); - } +#if !defined(NDEBUG) + if (initverbose) + log_message_class("Class has no static class initializer: ", c); +#endif return true; } /* Sun's and IBM's JVM don't care about the static flag */ /* if (!(m->flags & ACC_STATIC)) { */ -/* panic("Class initializer is not static!"); */ +/* log_text("Class initializer is not static!"); */ +#if !defined(NDEBUG) if (initverbose) log_message_class("Starting static class initializer for class: ", c); - -#if defined(USE_THREADS) && !defined(NATIVE_THREADS) - b = blockInts; - blockInts = 0; #endif /* now call the initializer */ - asm_calljavafunction(m, NULL, NULL, NULL, NULL); - -#if defined(USE_THREADS) && !defined(NATIVE_THREADS) - assert(blockInts == 0); - blockInts = b; -#endif + (void) vm_call_method(m, NULL); /* we have an exception or error */ - if (*exceptionptr) { - /* class is NOT initialized */ + xptr = *exceptionptr; - c->initialized = false; + if (xptr) { + /* class is NOT initialized and is marked with error */ - /* is this an exception, than wrap it */ - - if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) { - java_objectheader *xptr; - java_objectheader *cause; - - /* get the cause */ + c->state |= CLASS_ERROR; - cause = *exceptionptr; + /* is this an exception, than wrap it */ + if (builtin_instanceof(xptr, class_java_lang_Exception)) { /* clear exception, because we are calling jit code again */ *exceptionptr = NULL; /* wrap the exception */ - xptr = + *exceptionptr = new_exception_throwable(string_java_lang_ExceptionInInitializerError, - (java_lang_Throwable *) cause); - - /* XXX should we exit here? */ - - if (*exceptionptr) - throw_exception(); - - /* set new exception */ - - *exceptionptr = xptr; + (java_lang_Throwable *) xptr); } return false; } +#if !defined(NDEBUG) if (initverbose) log_message_class("Finished static class initializer for class: ", c); +#endif return true; }