diff --git a/src/builtin.cpp b/src/builtin.cpp index f3ad3c6ec5..f113bd5ead 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -85,7 +85,8 @@ Avian_avian_SystemClassLoader_resourceExists RUNTIME_ARRAY(char, n, stringLength(t, name) + 1); stringChars(t, name, RUNTIME_ARRAY_BODY(n)); - bool r = getFinder(t, loader)->exists(RUNTIME_ARRAY_BODY(n)); + bool r = static_cast(systemClassLoaderFinder(t, loader))->exists + (RUNTIME_ARRAY_BODY(n)); // fprintf(stderr, "resource %s exists? %d\n", n, r); diff --git a/src/classpath-common.h b/src/classpath-common.h index 3c65301de4..29d90753bb 100644 --- a/src/classpath-common.h +++ b/src/classpath-common.h @@ -176,7 +176,7 @@ loadLibrary(Thread* t, const char* name) } System::Library* lib; - if (LIKELY(t->m->system->success(t->m->system->load(&lib, name)))) { + if (t->m->system->success(t->m->system->load(&lib, name))) { last->setNext(lib); return lib; } else { diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index a3b41bbab6..b8b7256bdd 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -1602,6 +1602,7 @@ JVM_FindLoadedClass(Thread* t, jobject loader, jstring name) ENTER(t, Thread::ActiveState); object spec = makeByteArray(t, stringLength(t, *name) + 1); + { char* s = reinterpret_cast(&byteArrayBody(t, spec, 0)); stringChars(t, *name, s); replace('.', '/', s); diff --git a/src/compile.cpp b/src/compile.cpp index e0f1bbe00c..97e3767ec9 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -8226,8 +8226,8 @@ boot(MyThread* t, BootImage* image) syncInstructionCache(code, image->codeSize); - setRoot(t, Machine::ClassMap, makeClassMap - (t, bootClassTable, image->bootClassCount, heap)); + set(t, root(t, Machine::BootLoader), ClassLoaderMap, makeClassMap + (t, bootClassTable, image->bootClassCount, heap)); set(t, root(t, Machine::AppLoader), ClassLoaderMap, makeClassMap (t, appClassTable, image->appClassCount, heap)); @@ -8249,7 +8249,8 @@ boot(MyThread* t, BootImage* image) fixupVirtualThunks(t, image, code); - fixupMethods(t, root(t, Machine::ClassMap), image, code); + fixupMethods + (t, classLoaderMap(t, root(t, Machine::BootLoader)), image, code); fixupMethods(t, classLoaderMap(t, root(t, Machine::AppLoader)), image, code); setRoot(t, Machine::BootstrapClassMap, makeHashMap(t, 0, 0)); @@ -8657,6 +8658,24 @@ compile(MyThread* t, Allocator* allocator, BootContext* bootContext, compile(t, &context); if (UNLIKELY(t->exception)) return; + { object ehTable = codeExceptionHandlerTable(t, methodCode(t, clone)); + + if (ehTable) { + PROTECT(t, ehTable); + + // resolve all exception handler catch types before we acquire + // the class lock: + for (unsigned i = 0; i < exceptionHandlerTableLength(t, ehTable); ++i) { + ExceptionHandler* handler = exceptionHandlerTableBody(t, ehTable, i); + if (exceptionHandlerCatchType(handler)) { + resolveClassInPool + (t, clone, exceptionHandlerCatchType(handler) - 1); + if (UNLIKELY(t->exception)) return; + } + } + } + } + ACQUIRE(t, t->m->classLock); if (methodAddress(t, method) != defaultThunk(t)) { diff --git a/src/machine.cpp b/src/machine.cpp index d23c5ee1dd..df9cf6c510 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1785,15 +1785,15 @@ makeArrayClass(Thread* t, object loader, object spec, bool throw_) object elementClass = hashMapFind (t, root(t, Machine::BootstrapClassMap), elementSpec, byteArrayHash, byteArrayEqual); - + if (elementClass == 0) { elementClass = resolveClass(t, loader, elementSpec, throw_); if (elementClass == 0) return 0; } - object class_ = hashMapFind - (t, getClassLoaderMap(t, classLoader(t, elementClass)), spec, - byteArrayHash, byteArrayEqual); + PROTECT(t, elementClass); + + object class_ = findLoadedClass(t, classLoader(t, elementClass), spec); return class_ ? class_ : makeArrayClass (t, classLoader(t, elementClass), dimensions, spec, elementClass); @@ -2002,12 +2002,18 @@ boot(Thread* t) set(t, type(t, Machine::DoubleArrayType), ClassStaticTable, type(t, Machine::JdoubleType)); - setRoot(t, Machine::ClassMap, makeHashMap(t, 0, 0)); + { object map = makeHashMap(t, 0, 0); + set(t, root(t, Machine::BootLoader), ClassLoaderMap, map); + } + + systemClassLoaderFinder(t, root(t, Machine::BootLoader)) = m->bootFinder; { object map = makeHashMap(t, 0, 0); set(t, root(t, Machine::AppLoader), ClassLoaderMap, map); } + systemClassLoaderFinder(t, root(t, Machine::AppLoader)) = m->appFinder; + set(t, root(t, Machine::AppLoader), ClassLoaderParent, root(t, Machine::BootLoader)); @@ -3127,7 +3133,7 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_) ACQUIRE(t, t->m->classLock); object class_ = hashMapFind - (t, getClassLoaderMap(t, loader), spec, byteArrayHash, byteArrayEqual); + (t, classLoaderMap(t, loader), spec, byteArrayHash, byteArrayEqual); if (class_ == 0) { if (classLoaderParent(t, loader)) { @@ -3149,7 +3155,8 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_) ".class", 7); - System::Region* region = getFinder(t, loader)->find + System::Region* region = static_cast + (systemClassLoaderFinder(t, loader))->find (RUNTIME_ARRAY_BODY(file)); if (region) { @@ -3185,8 +3192,7 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_) if (class_) { PROTECT(t, class_); - hashMapInsert - (t, getClassLoaderMap(t, loader), spec, class_, byteArrayHash); + hashMapInsert(t, classLoaderMap(t, loader), spec, class_, byteArrayHash); } else if (throw_ and t->exception == 0) { object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); t->exception = t->m->classpath->makeThrowable @@ -3200,48 +3206,34 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_) object findLoadedClass(Thread* t, object loader, object spec) { + PROTECT(t, loader); PROTECT(t, spec); + ACQUIRE(t, t->m->classLock); - object map = getClassLoaderMap(t, loader); - if (map) { - return hashMapFind(t, map, spec, byteArrayHash, byteArrayEqual); - } else { - return 0; - } + return classLoaderMap(t, loader) ? hashMapFind + (t, classLoaderMap(t, loader), spec, byteArrayHash, byteArrayEqual) : 0; } object resolveClass(Thread* t, object loader, object spec, bool throw_) { - if (loader == root(t, Machine::BootLoader) - or loader == root(t, Machine::AppLoader)) - { + if (objectClass(t, loader) == type(t, Machine::SystemClassLoaderType)) { return resolveSystemClass(t, loader, spec, throw_); } else { expect(t, throw_); - PROTECT(t, loader); - PROTECT(t, spec); - - { ACQUIRE(t, t->m->classLock); - - if (classLoaderMap(t, loader) == 0) { - object map = makeHashMap(t, 0, 0); - set(t, loader, ClassLoaderMap, map); - } - - object class_ = hashMapFind - (t, classLoaderMap(t, loader), spec, byteArrayHash, byteArrayEqual); - - if (class_) { - return class_; + { object c = findLoadedClass(t, loader, spec); + if (c) { + return c; } } - object class_; + PROTECT(t, loader); + PROTECT(t, spec); + if (byteArrayBody(t, spec, 0) == '[') { - class_ = resolveArrayClass(t, loader, spec, throw_); + return resolveArrayClass(t, loader, spec, throw_); } else { if (root(t, Machine::LoadClassMethod) == 0) { object m = resolveMethod @@ -3272,31 +3264,38 @@ resolveClass(Thread* t, object loader, object spec, bool throw_) replace('/', '.', RUNTIME_ARRAY_BODY(s), reinterpret_cast (&byteArrayBody(t, spec, 0))); - object specString = makeString(t, "%s", s); + object specString = makeString(t, "%s", RUNTIME_ARRAY_BODY(s)); - class_ = t->m->processor->invoke(t, method, loader, specString); + object c = t->m->processor->invoke(t, method, loader, specString); - if (LIKELY(class_ and t->exception == 0)) { - class_ = jclassVmClass(t, class_); + if (LIKELY(c and t->exception == 0)) { + PROTECT(t, c); + + ACQUIRE(t, t->m->classLock); + + if (classLoaderMap(t, loader) == 0) { + object map = makeHashMap(t, 0, 0); + set(t, loader, ClassLoaderMap, map); + } + + c = jclassVmClass(t, c); + + hashMapInsert + (t, classLoaderMap(t, loader), spec, c, byteArrayHash); + + return c; } } } + + if (t->exception == 0) { + object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); + t->exception = t->m->classpath->makeThrowable + (t, Machine::ClassNotFoundExceptionType, message); + } + + return 0; } - - if (class_) { - PROTECT(t, class_); - - ACQUIRE(t, t->m->classLock); - - hashMapInsert(t, classLoaderMap(t, loader), spec, class_, - byteArrayHash); - } else if (throw_ and t->exception == 0) { - object message = makeString(t, "%s", &byteArrayBody(t, spec, 0)); - t->exception = t->m->classpath->makeThrowable - (t, Machine::ClassNotFoundExceptionType, message); - } - - return class_; } } @@ -3411,6 +3410,7 @@ preInitClass(Thread* t, object c) if (classVmFlags(t, c) & NeedInitFlag) { PROTECT(t, c); ACQUIRE(t, t->m->classLock); + if (classVmFlags(t, c) & NeedInitFlag) { if (classVmFlags(t, c) & InitFlag) { // If the class is currently being initialized and this the thread @@ -3444,8 +3444,8 @@ void postInitClass(Thread* t, object c) { PROTECT(t, c); - ACQUIRE(t, t->m->classLock); + if (t->exception) { t->exception = t->m->classpath->makeThrowable (t, Machine::ExceptionInInitializerErrorType, 0, 0, t->exception); @@ -3960,13 +3960,15 @@ defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length) if (c) { PROTECT(t, c); - if (getClassLoaderMap(t, loader) == 0) { + ACQUIRE(t, t->m->classLock); + + if (classLoaderMap(t, loader) == 0) { object map = makeHashMap(t, 0, 0); set(t, loader, ClassLoaderMap, map); } - hashMapInsert(t, getClassLoaderMap(t, loader), className(t, c), c, - byteArrayHash); + hashMapInsert + (t, classLoaderMap(t, loader), className(t, c), c, byteArrayHash); } return c; diff --git a/src/machine.h b/src/machine.h index 4030458089..7263994b1d 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1188,9 +1188,9 @@ class Machine { enum Root { BootLoader, AppLoader, - ClassMap, - LoadClassMethod, BootstrapClassMap, + FindLoadedClassMethod, + LoadClassMethod, MonitorMap, StringMap, ByteArrayMap, @@ -1777,28 +1777,6 @@ setType(Thread* t, Machine::Type type, object value) set(t, t->m->types, ArrayBody + (type * BytesPerWord), value); } -inline object -getClassLoaderMap(Thread* t, object loader) -{ - if (loader == root(t, Machine::BootLoader)) { - return root(t, Machine::ClassMap); - } else { - return classLoaderMap(t, loader); - } -} - -inline Finder* -getFinder(Thread* t, object loader) -{ - if (loader == root(t, Machine::BootLoader)) { - return t->m->bootFinder; - } else if (loader == root(t, Machine::AppLoader)) { - return t->m->appFinder; - } else { - abort(t); - } -} - inline bool objectFixed(Thread*, object o) { diff --git a/src/types.def b/src/types.def index 854798c84e..996b99e377 100644 --- a/src/types.def +++ b/src/types.def @@ -22,7 +22,8 @@ (type classLoader java/lang/ClassLoader (object map)) -(type systemClassLoader avian/SystemClassLoader) +(type systemClassLoader avian/SystemClassLoader + (void* finder)) (type field avian/VMField)