diff --git a/src/classpath-avian.cpp b/src/classpath-avian.cpp index 5e68d2ed14..ddef6c36de 100644 --- a/src/classpath-avian.cpp +++ b/src/classpath-avian.cpp @@ -88,6 +88,12 @@ class MyClasspath : public Classpath { return AVIAN_CLASSPATH; } + virtual void + updatePackageMap(Thread*, object) + { + // ignore + } + virtual void dispose() { diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index 47b6b12d8a..dd772f2eeb 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -638,6 +638,47 @@ class MyClasspath : public Classpath { return classpath; } + virtual void + updatePackageMap(Thread* t, object class_) + { + PROTECT(t, class_); + + if (root(t, Machine::PackageMap) == 0) { + setRoot(t, Machine::PackageMap, makeHashMap(t, 0, 0)); + } + + object className = vm::className(t, class_); + if ('[' != byteArrayBody(t, className, 0)) { + THREAD_RUNTIME_ARRAY + (t, char, packageName, byteArrayLength(t, className)); + + char* s = reinterpret_cast(&byteArrayBody(t, className, 0)); + char* p = strrchr(s, '/'); + + if (p) { + int length = (p - s) + 1; + memcpy(RUNTIME_ARRAY_BODY(packageName), + &byteArrayBody(t, className, 0), + length); + RUNTIME_ARRAY_BODY(packageName)[length] = 0; + + object key = vm::makeByteArray(t, "%s", packageName); + + hashMapRemove + (t, root(t, Machine::PackageMap), key, byteArrayHash, + byteArrayEqual); + + object source = classSource(t, class_); + if (source == 0) { + source = vm::makeByteArray(t, "avian-dummy-package-source"); + } + + hashMapInsert + (t, root(t, Machine::PackageMap), key, source, byteArrayHash); + } + } + } + virtual void dispose() { @@ -3531,10 +3572,37 @@ EXPORT(JVM_ClassDepth)(Thread*, jstring) { abort(); } extern "C" JNIEXPORT jint JNICALL EXPORT(JVM_ClassLoaderDepth)(Thread*) { abort(); } -extern "C" JNIEXPORT jstring JNICALL -EXPORT(JVM_GetSystemPackage)(Thread*, jstring s) +uint64_t +jvmGetSystemPackage(Thread* t, uintptr_t* arguments) { - return s; + jstring s = reinterpret_cast(arguments[0]); + + ACQUIRE(t, t->m->classLock); + + THREAD_RUNTIME_ARRAY(t, char, chars, stringLength(t, *s) + 1); + stringChars(t, *s, RUNTIME_ARRAY_BODY(chars)); + + object key = makeByteArray(t, RUNTIME_ARRAY_BODY(chars)); + + object array = hashMapFind + (t, root(t, Machine::PackageMap), key, byteArrayHash, byteArrayEqual); + + if (array) { + return reinterpret_cast + (makeLocalReference + (t, t->m->classpath->makeString + (t, array, 0, byteArrayLength(t, array)))); + } else { + return 0; + } +} + +extern "C" JNIEXPORT jstring JNICALL +EXPORT(JVM_GetSystemPackage)(Thread* t, jstring s) +{ + uintptr_t arguments[] = { reinterpret_cast(s) }; + + return reinterpret_cast(run(t, jvmGetSystemPackage, arguments)); } uint64_t diff --git a/src/machine.cpp b/src/machine.cpp index 4f01f204da..09a314b9f2 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -4099,6 +4099,8 @@ resolveSystemClass(Thread* t, object loader, object spec, bool throw_, if (class_) { hashMapInsert(t, classLoaderMap(t, loader), spec, class_, byteArrayHash); + + t->m->classpath->updatePackageMap(t, class_); } else if (throw_) { throwNew(t, throwType, "%s", &byteArrayBody(t, spec, 0)); } diff --git a/src/machine.h b/src/machine.h index 35d07a78e9..52233cab3c 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1206,6 +1206,7 @@ class Machine { BootLoader, AppLoader, BootstrapClassMap, + PackageMap, FindLoadedClassMethod, LoadClassMethod, MonitorMap, @@ -1550,6 +1551,9 @@ class Classpath { virtual const char* bootClasspath() = 0; + virtual void + updatePackageMap(Thread* t, object class_) = 0; + virtual void dispose() = 0; };