Remove class root duplicates from well known classes.
And get well known exception classes as declaring classes
of their constructors.
Also change function `ThreadForEnv()` to `Thread::ForEnv()`
and use it where appropriate, mostly in code added recently
while cleaning up well-known methods.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I2ededa429863a6cddbcbb879a223277fd6245557
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 31ce731..d1d3190 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -44,7 +44,7 @@
#include "oat_quick_method_header.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
-#include "thread.h"
+#include "thread-inl.h"
extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_bar(JNIEnv*, jobject, jint count) {
return count + 1;
@@ -407,7 +407,7 @@
jobject JniCompilerTest::class_loader_;
void JniCompilerTest::AssertCallerObjectLocked(JNIEnv* env) {
- Thread* self = down_cast<JNIEnvExt*>(env)->GetSelf();
+ Thread* self = Thread::ForEnv(env);
CHECK_EQ(self, Thread::Current());
ScopedObjectAccess soa(self);
ArtMethod** caller_frame = self->GetManagedStack()->GetTopQuickFrame();
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index bb39256..f199ede 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -1603,8 +1603,7 @@
mirror::Throwable* exception = soa.Self()->GetException();
DCHECK(exception != nullptr);
VLOG(compiler) << "Exception during type resolution: " << exception->Dump();
- if (exception->GetClass() ==
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_OutOfMemoryError)) {
+ if (exception->GetClass() == WellKnownClasses::java_lang_OutOfMemoryError.Get()) {
// There's little point continuing compilation if the heap is exhausted.
// Trying to do so would also introduce non-deterministic compilation results.
LOG(FATAL) << "Out of memory during type resolution for compilation";
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index a51e28f..7a68863 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -536,10 +536,9 @@
static void WrapExceptionInInitializer(Handle<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_) {
Thread* self = Thread::Current();
- JNIEnv* env = self->GetJniEnv();
- ScopedLocalRef<jthrowable> cause(env, env->ExceptionOccurred());
- CHECK(cause.get() != nullptr);
+ ObjPtr<mirror::Throwable> cause = self->GetException();
+ CHECK(cause != nullptr);
// Boot classpath classes should not fail initialization. This is a consistency debug check.
// This cannot in general be guaranteed, but in all likelihood leads to breakage down the line.
@@ -554,12 +553,8 @@
<< self->GetException()->Dump();
}
- env->ExceptionClear();
- bool is_error = env->IsInstanceOf(cause.get(), WellKnownClasses::java_lang_Error);
- env->Throw(cause.get());
-
// We only wrap non-Error exceptions; an Error can just be used as-is.
- if (!is_error) {
+ if (!cause->IsError()) {
self->ThrowNewWrappedException("Ljava/lang/ExceptionInInitializerError;", nullptr);
}
VlogClassInitializationFailure(klass);
@@ -1132,14 +1127,6 @@
// classes are always in the boot image, so this code is primarily intended
// for running without boot image but may be needed for boot image if the
// AOT-initialization fails due to introduction of new code to `<clinit>`.
- jclass classes_to_initialize[] = {
- // Initialize `StackOverflowError`.
- WellKnownClasses::java_lang_StackOverflowError,
- };
- auto* vm = down_cast<JNIEnvExt*>(self->GetJniEnv())->GetVm();
- for (jclass c : classes_to_initialize) {
- EnsureRootInitialized(this, self, ObjPtr<mirror::Class>::DownCast(vm->DecodeGlobal(c)));
- }
ArtMethod* static_methods_of_classes_to_initialize[] = {
// Initialize primitive boxing classes (avoid check at runtime).
WellKnownClasses::java_lang_Boolean_valueOf,
@@ -1150,6 +1137,8 @@
WellKnownClasses::java_lang_Integer_valueOf,
WellKnownClasses::java_lang_Long_valueOf,
WellKnownClasses::java_lang_Short_valueOf,
+ // Initialize `StackOverflowError`.
+ WellKnownClasses::java_lang_StackOverflowError_init,
// Ensure class loader classes are initialized (avoid check at runtime).
// Superclass `ClassLoader` is a class root and already initialized above.
// Superclass `BaseDexClassLoader` is initialized implicitly.
diff --git a/runtime/class_loader_context_test.cc b/runtime/class_loader_context_test.cc
index d89c5b6..ce9780a 100644
--- a/runtime/class_loader_context_test.cc
+++ b/runtime/class_loader_context_test.cc
@@ -24,6 +24,7 @@
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "art_field-inl.h"
+#include "art_method-alloc-inl.h"
#include "base/dchecked_vector.h"
#include "base/stl_util.h"
#include "class_linker.h"
@@ -1362,13 +1363,14 @@
static jobject CreateForeignClassLoader() {
ScopedObjectAccess soa(Thread::Current());
- JNIEnv* env = soa.Env();
// We cannot instantiate a ClassLoader directly, so instead we allocate an Object to represent
// our foreign ClassLoader (this works because the runtime does proper instanceof checks before
// operating on this object.
- jmethodID ctor = env->GetMethodID(WellKnownClasses::java_lang_Object, "<init>", "()V");
- return env->NewObject(WellKnownClasses::java_lang_Object, ctor);
+ ArtMethod* ctor =
+ GetClassRoot<mirror::Object>()->FindClassMethod("<init>", "()V", kRuntimePointerSize);
+ CHECK(ctor != nullptr);
+ return soa.AddLocalReference<jobject>(ctor->NewObject<>(soa.Self()));
}
TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedBase) {
diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc
index 75918a7..5182689 100644
--- a/runtime/common_throws.cc
+++ b/runtime/common_throws.cc
@@ -714,13 +714,12 @@
msg += PrettySize(self->GetStackSize());
ScopedObjectAccessUnchecked soa(self);
- StackHandleScope<2u> hs(self);
- Handle<mirror::Class> j_l_soe = hs.NewHandle(
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_StackOverflowError));
- DCHECK(j_l_soe->IsInitialized());
+ StackHandleScope<1u> hs(self);
// Allocate an uninitialized object.
- Handle<mirror::Object> exc = hs.NewHandle(j_l_soe->AllocObject(self));
+ DCHECK(WellKnownClasses::java_lang_StackOverflowError->IsInitialized());
+ Handle<mirror::Object> exc = hs.NewHandle(
+ WellKnownClasses::java_lang_StackOverflowError->AllocObject(self));
if (exc == nullptr) {
LOG(WARNING) << "Could not allocate StackOverflowError object.";
return;
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index ba9d48a..8bf3aee 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -581,10 +581,11 @@
if (kIsDebugBuild && !cc->use_generational_cc_) {
cc->region_space_->AssertAllRegionLiveBytesZeroOrCleared();
}
- if (UNLIKELY(Runtime::Current()->IsActiveTransaction())) {
- CHECK(Runtime::Current()->IsAotCompiler());
+ Runtime* runtime = Runtime::Current();
+ if (UNLIKELY(runtime->IsActiveTransaction())) {
+ CHECK(runtime->IsAotCompiler());
TimingLogger::ScopedTiming split3("(Paused)VisitTransactionRoots", cc->GetTimings());
- Runtime::Current()->VisitTransactionRoots(cc);
+ runtime->VisitTransactionRoots(cc);
}
if (kUseBakerReadBarrier && kGrayDirtyImmuneObjects) {
cc->GrayAllNewlyDirtyImmuneObjects();
@@ -593,15 +594,10 @@
cc->VerifyGrayImmuneObjects();
}
}
- // May be null during runtime creation, in this case leave java_lang_Object null.
- // This is safe since single threaded behavior should mean FillWithFakeObject does not
- // happen when java_lang_Object_ is null.
- if (WellKnownClasses::java_lang_Object != nullptr) {
- cc->java_lang_Object_ = down_cast<mirror::Class*>(cc->Mark(thread,
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_Object).Ptr()));
- } else {
- cc->java_lang_Object_ = nullptr;
- }
+ ObjPtr<mirror::Class> java_lang_Object =
+ GetClassRoot<mirror::Object, kWithoutReadBarrier>(runtime->GetClassLinker());
+ DCHECK(java_lang_Object != nullptr);
+ cc->java_lang_Object_ = down_cast<mirror::Class*>(cc->Mark(thread, java_lang_Object.Ptr()));
}
private:
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 3bda43d..f3bb166 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -103,6 +103,7 @@
#include "runtime.h"
#include "javaheapprof/javaheapsampler.h"
#include "scoped_thread_state_change-inl.h"
+#include "thread-inl.h"
#include "thread_list.h"
#include "verify_object-inl.h"
#include "well_known_classes.h"
@@ -4147,7 +4148,7 @@
// About kNotifyNativeInterval allocations have occurred. Check whether we should garbage collect.
void Heap::NotifyNativeAllocations(JNIEnv* env) {
native_objects_notified_.fetch_add(kNotifyNativeInterval, std::memory_order_relaxed);
- CheckGCForNative(ThreadForEnv(env));
+ CheckGCForNative(Thread::ForEnv(env));
}
// Register a native allocation with an explicit size.
@@ -4161,7 +4162,7 @@
native_objects_notified_.fetch_add(1, std::memory_order_relaxed);
if (objects_notified % kNotifyNativeInterval == kNotifyNativeInterval - 1
|| bytes > kCheckImmediatelyThreshold) {
- CheckGCForNative(ThreadForEnv(env));
+ CheckGCForNative(Thread::ForEnv(env));
}
// Heap profiler treats this as a Java allocation with a null object.
JHPCheckNonTlabSampleAllocation(Thread::Current(), nullptr, bytes);
diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc
index b538fa9..a38ba1c 100644
--- a/runtime/mirror/throwable.cc
+++ b/runtime/mirror/throwable.cc
@@ -31,7 +31,7 @@
#include "object_array.h"
#include "stack_trace_element-inl.h"
#include "string.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
namespace mirror {
@@ -70,14 +70,14 @@
}
bool Throwable::IsCheckedException() {
- if (InstanceOf(WellKnownClasses::ToClass(WellKnownClasses::java_lang_Error))) {
+ if (IsError()) {
return false;
}
- return !InstanceOf(WellKnownClasses::ToClass(WellKnownClasses::java_lang_RuntimeException));
+ return !InstanceOf(WellKnownClasses::java_lang_RuntimeException.Get());
}
bool Throwable::IsError() {
- return InstanceOf(WellKnownClasses::ToClass(WellKnownClasses::java_lang_Error));
+ return InstanceOf(WellKnownClasses::java_lang_Error.Get());
}
int32_t Throwable::GetStackDepth() {
diff --git a/runtime/native/dalvik_system_BaseDexClassLoader.cc b/runtime/native/dalvik_system_BaseDexClassLoader.cc
index 5c127d0..a4f702c 100644
--- a/runtime/native/dalvik_system_BaseDexClassLoader.cc
+++ b/runtime/native/dalvik_system_BaseDexClassLoader.cc
@@ -23,6 +23,7 @@
#include "mirror/object_array-alloc-inl.h"
#include "native_util.h"
#include "nativehelper/jni_macros.h"
+#include "thread-inl.h"
namespace art {
@@ -47,7 +48,7 @@
CHECK(class_loader != nullptr);
std::map<std::string, std::string> context_map =
ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
- Thread* self = down_cast<JNIEnvExt*>(env)->GetSelf();
+ Thread* self = Thread::ForEnv(env);
ScopedObjectAccess soa(self);
StackHandleScope<1u> hs(self);
Handle<mirror::ObjectArray<mirror::String>> array = hs.NewHandle(
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 21e7f77..f2c9efc 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -55,6 +55,7 @@
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "string_array_utils.h"
+#include "thread-current-inl.h"
namespace art {
@@ -509,7 +510,7 @@
}
// Now create output array and copy the set into it.
- ScopedObjectAccess soa(down_cast<JNIEnvExt*>(env)->GetSelf());
+ ScopedObjectAccess soa(Thread::ForEnv(env));
auto descriptor_to_dot = [](const char* descriptor) { return DescriptorToDot(descriptor); };
return soa.AddLocalReference<jobjectArray>(CreateStringArray(
soa.Self(),
@@ -645,7 +646,7 @@
OatFileAssistant::GetOptimizationStatus(
filename.c_str(), target_instruction_set, &compilation_filter, &compilation_reason);
- ScopedObjectAccess soa(down_cast<JNIEnvExt*>(env)->GetSelf());
+ ScopedObjectAccess soa(Thread::ForEnv(env));
return soa.AddLocalReference<jobjectArray>(CreateStringArray(soa.Self(), {
compilation_filter.c_str(),
compilation_reason.c_str()
@@ -900,7 +901,7 @@
filenames[1] = vdex_filename.c_str();
used_filenames = ArrayRef<const char* const>(filenames, 2u);
}
- ScopedObjectAccess soa(down_cast<JNIEnvExt*>(env)->GetSelf());
+ ScopedObjectAccess soa(Thread::ForEnv(env));
return soa.AddLocalReference<jobjectArray>(CreateStringArray(soa.Self(), used_filenames));
}
diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc
index 2c651df..d44fcc8 100644
--- a/runtime/native/dalvik_system_VMDebug.cc
+++ b/runtime/native/dalvik_system_VMDebug.cc
@@ -48,14 +48,14 @@
#include "nativehelper/scoped_utf_chars.h"
#include "scoped_fast_native_object_access-inl.h"
#include "string_array_utils.h"
+#include "thread-inl.h"
#include "trace.h"
namespace art {
static jobjectArray VMDebug_getVmFeatureList(JNIEnv* env, jclass) {
- Thread* self = down_cast<JNIEnvExt*>(env)->GetSelf();
- ScopedObjectAccess soa(self);
- return soa.AddLocalReference<jobjectArray>(CreateStringArray(self, {
+ ScopedObjectAccess soa(Thread::ForEnv(env));
+ return soa.AddLocalReference<jobjectArray>(CreateStringArray(soa.Self(), {
"method-trace-profiling",
"method-trace-profiling-streaming",
"method-sample-profiling",
@@ -380,7 +380,7 @@
}
static jobjectArray VMDebug_getRuntimeStatsInternal(JNIEnv* env, jclass) {
- Thread* self = down_cast<JNIEnvExt*>(env)->GetSelf();
+ Thread* self = Thread::ForEnv(env);
ScopedObjectAccess soa(self);
StackHandleScope<1u> hs(self);
int32_t size = enum_cast<int32_t>(VMDebugRuntimeStatId::kNumRuntimeStats);
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index a881879..74202fc 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -62,7 +62,7 @@
#include "scoped_fast_native_object_access-inl.h"
#include "scoped_thread_state_change-inl.h"
#include "string_array_utils.h"
-#include "thread.h"
+#include "thread-inl.h"
#include "thread_list.h"
namespace art {
@@ -191,7 +191,7 @@
static jobjectArray VMRuntime_properties(JNIEnv* env, jobject) {
const std::vector<std::string>& properties = Runtime::Current()->GetProperties();
- ScopedObjectAccess soa(down_cast<JNIEnvExt*>(env)->GetSelf());
+ ScopedObjectAccess soa(Thread::ForEnv(env));
return soa.AddLocalReference<jobjectArray>(CreateStringArray(soa.Self(), properties));
}
@@ -327,31 +327,31 @@
}
static void VMRuntime_trimHeap(JNIEnv* env, jobject) {
- Runtime::Current()->GetHeap()->Trim(ThreadForEnv(env));
+ Runtime::Current()->GetHeap()->Trim(Thread::ForEnv(env));
}
static void VMRuntime_requestHeapTrim(JNIEnv* env, jobject) {
- Runtime::Current()->GetHeap()->RequestTrim(ThreadForEnv(env));
+ Runtime::Current()->GetHeap()->RequestTrim(Thread::ForEnv(env));
}
static void VMRuntime_requestConcurrentGC(JNIEnv* env, jobject) {
gc::Heap *heap = Runtime::Current()->GetHeap();
- heap->RequestConcurrentGC(ThreadForEnv(env),
+ heap->RequestConcurrentGC(Thread::ForEnv(env),
gc::kGcCauseBackground,
true,
heap->GetCurrentGcNum());
}
static void VMRuntime_startHeapTaskProcessor(JNIEnv* env, jobject) {
- Runtime::Current()->GetHeap()->GetTaskProcessor()->Start(ThreadForEnv(env));
+ Runtime::Current()->GetHeap()->GetTaskProcessor()->Start(Thread::ForEnv(env));
}
static void VMRuntime_stopHeapTaskProcessor(JNIEnv* env, jobject) {
- Runtime::Current()->GetHeap()->GetTaskProcessor()->Stop(ThreadForEnv(env));
+ Runtime::Current()->GetHeap()->GetTaskProcessor()->Stop(Thread::ForEnv(env));
}
static void VMRuntime_runHeapTasks(JNIEnv* env, jobject) {
- Runtime::Current()->GetHeap()->GetTaskProcessor()->RunAllTasks(ThreadForEnv(env));
+ Runtime::Current()->GetHeap()->GetTaskProcessor()->RunAllTasks(Thread::ForEnv(env));
}
static void VMRuntime_preloadDexCaches(JNIEnv* env ATTRIBUTE_UNUSED, jobject) {
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 15188e9..f7d7d80 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -257,7 +257,7 @@
runtime->PreZygoteFork();
// Grab thread before fork potentially makes Thread::pthread_key_self_ unusable.
- return reinterpret_cast<jlong>(ThreadForEnv(env));
+ return reinterpret_cast<jlong>(Thread::ForEnv(env));
}
static void ZygoteHooks_nativePostZygoteFork(JNIEnv*, jclass) {
diff --git a/runtime/native/java_lang_VMClassLoader.cc b/runtime/native/java_lang_VMClassLoader.cc
index b327e51..b9c72b8 100644
--- a/runtime/native/java_lang_VMClassLoader.cc
+++ b/runtime/native/java_lang_VMClassLoader.cc
@@ -35,7 +35,8 @@
#include "obj_ptr.h"
#include "scoped_fast_native_object_access-inl.h"
#include "string_array_utils.h"
-#include "well_known_classes.h"
+#include "thread-inl.h"
+#include "well_known_classes-inl.h"
namespace art {
@@ -96,12 +97,9 @@
if (c != nullptr && c->IsErroneous()) {
cl->ThrowEarlierClassFailure(c);
Thread* self = soa.Self();
- ObjPtr<mirror::Class> iae_class =
- self->DecodeJObject(WellKnownClasses::java_lang_IllegalAccessError)->AsClass();
- ObjPtr<mirror::Class> ncdfe_class =
- self->DecodeJObject(WellKnownClasses::java_lang_NoClassDefFoundError)->AsClass();
- ObjPtr<mirror::Class> exception = self->GetException()->GetClass();
- if (exception == iae_class || exception == ncdfe_class) {
+ ObjPtr<mirror::Class> exception_class = self->GetException()->GetClass();
+ if (exception_class == WellKnownClasses::java_lang_IllegalAccessError ||
+ exception_class == WellKnownClasses::java_lang_NoClassDefFoundError) {
self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
c->PrettyDescriptor().c_str());
}
@@ -159,7 +157,7 @@
return is_base_dex(dex_file);
};
auto get_location = [](const DexFile* dex_file) { return dex_file->GetLocation(); };
- ScopedObjectAccess soa(down_cast<JNIEnvExt*>(env)->GetSelf());
+ ScopedObjectAccess soa(Thread::ForEnv(env));
return soa.AddLocalReference<jobjectArray>(CreateStringArray(
soa.Self(),
jar_count,
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index f25d446..0560223 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -2166,20 +2166,26 @@
// By setting calling class to java.lang.Object, the caller location for these
// JNI libs is core-oj.jar in the ART APEX, and hence they are loaded from the
// com_android_art linker namespace.
+ jclass java_lang_Object;
+ {
+ ScopedObjectAccess soa(self);
+ java_lang_Object = reinterpret_cast<jclass>(
+ GetJavaVM()->AddGlobalRef(self, GetClassRoot<mirror::Object>(GetClassLinker())));
+ }
// libicu_jni has to be initialized before libopenjdk{d} due to runtime dependency from
// libopenjdk{d} to Icu4cMetadata native methods in libicu_jni. See http://b/143888405
{
std::string error_msg;
if (!java_vm_->LoadNativeLibrary(
- env, "libicu_jni.so", nullptr, WellKnownClasses::java_lang_Object, &error_msg)) {
+ env, "libicu_jni.so", nullptr, java_lang_Object, &error_msg)) {
LOG(FATAL) << "LoadNativeLibrary failed for \"libicu_jni.so\": " << error_msg;
}
}
{
std::string error_msg;
if (!java_vm_->LoadNativeLibrary(
- env, "libjavacore.so", nullptr, WellKnownClasses::java_lang_Object, &error_msg)) {
+ env, "libjavacore.so", nullptr, java_lang_Object, &error_msg)) {
LOG(FATAL) << "LoadNativeLibrary failed for \"libjavacore.so\": " << error_msg;
}
}
@@ -2189,10 +2195,11 @@
: "libopenjdk.so";
std::string error_msg;
if (!java_vm_->LoadNativeLibrary(
- env, kOpenJdkLibrary, nullptr, WellKnownClasses::java_lang_Object, &error_msg)) {
+ env, kOpenJdkLibrary, nullptr, java_lang_Object, &error_msg)) {
LOG(FATAL) << "LoadNativeLibrary failed for \"" << kOpenJdkLibrary << "\": " << error_msg;
}
}
+ env->DeleteGlobalRef(java_lang_Object);
// Initialize well known classes that may invoke runtime native methods.
WellKnownClasses::LateInit(env);
diff --git a/runtime/scoped_thread_state_change-inl.h b/runtime/scoped_thread_state_change-inl.h
index d601952..674d791 100644
--- a/runtime/scoped_thread_state_change-inl.h
+++ b/runtime/scoped_thread_state_change-inl.h
@@ -94,7 +94,7 @@
}
inline ScopedObjectAccessAlreadyRunnable::ScopedObjectAccessAlreadyRunnable(JNIEnv* env)
- : self_(ThreadForEnv(env)), env_(down_cast<JNIEnvExt*>(env)), vm_(env_->GetVm()) {}
+ : self_(Thread::ForEnv(env)), env_(down_cast<JNIEnvExt*>(env)), vm_(env_->GetVm()) {}
inline ScopedObjectAccessAlreadyRunnable::ScopedObjectAccessAlreadyRunnable(Thread* self)
: self_(self),
diff --git a/runtime/thread-inl.h b/runtime/thread-inl.h
index 4110ed2..a99977f 100644
--- a/runtime/thread-inl.h
+++ b/runtime/thread-inl.h
@@ -34,7 +34,7 @@
namespace art {
// Quickly access the current thread from a JNIEnv.
-static inline Thread* ThreadForEnv(JNIEnv* env) {
+inline Thread* Thread::ForEnv(JNIEnv* env) {
JNIEnvExt* full_env(down_cast<JNIEnvExt*>(env));
return full_env->GetSelf();
}
diff --git a/runtime/thread.cc b/runtime/thread.cc
index da403b5..a8b0e17 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2495,8 +2495,7 @@
void Thread::AssertPendingOOMException() const {
AssertPendingException();
auto* e = GetException();
- CHECK_EQ(e->GetClass(), DecodeJObject(WellKnownClasses::java_lang_OutOfMemoryError)->AsClass())
- << e->Dump();
+ CHECK_EQ(e->GetClass(), WellKnownClasses::java_lang_OutOfMemoryError.Get()) << e->Dump();
}
void Thread::AssertNoPendingException() const {
diff --git a/runtime/thread.h b/runtime/thread.h
index e6b419d..2613b15 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -248,6 +248,9 @@
// TODO: mark as PURE so the compiler may coalesce and remove?
static Thread* Current();
+ // Get the thread from the JNI environment.
+ static Thread* ForEnv(JNIEnv* env);
+
// On a runnable thread, check for pending thread suspension request and handle if pending.
void AllowThreadSuspension() REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 771df58..397f2bd 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -49,16 +49,8 @@
jclass WellKnownClasses::dalvik_annotation_optimization_FastNative;
jclass WellKnownClasses::dalvik_annotation_optimization_NeverCompile;
jclass WellKnownClasses::dalvik_annotation_optimization_NeverInline;
-jclass WellKnownClasses::dalvik_system_EmulatedStackFrame;
jclass WellKnownClasses::java_lang_annotation_Annotation__array;
-jclass WellKnownClasses::java_lang_Error;
-jclass WellKnownClasses::java_lang_IllegalAccessError;
-jclass WellKnownClasses::java_lang_NoClassDefFoundError;
-jclass WellKnownClasses::java_lang_Object;
-jclass WellKnownClasses::java_lang_OutOfMemoryError;
jclass WellKnownClasses::java_lang_reflect_Parameter__array;
-jclass WellKnownClasses::java_lang_RuntimeException;
-jclass WellKnownClasses::java_lang_StackOverflowError;
jclass WellKnownClasses::java_lang_StringFactory;
jclass WellKnownClasses::java_lang_System;
jclass WellKnownClasses::java_lang_Void;
@@ -81,28 +73,34 @@
ArtMethod* WellKnownClasses::java_lang_Daemons_waitForDaemonStart;
ArtMethod* WellKnownClasses::java_lang_Double_doubleToRawLongBits;
ArtMethod* WellKnownClasses::java_lang_Double_valueOf;
+ArtMethod* WellKnownClasses::java_lang_Error_init;
ArtMethod* WellKnownClasses::java_lang_Float_floatToRawIntBits;
ArtMethod* WellKnownClasses::java_lang_Float_valueOf;
+ArtMethod* WellKnownClasses::java_lang_IllegalAccessError_init;
ArtMethod* WellKnownClasses::java_lang_Integer_valueOf;
-ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandle_asType;
-ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact;
-ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandles_lookup;
-ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandles_Lookup_findConstructor;
ArtMethod* WellKnownClasses::java_lang_Long_valueOf;
-ArtMethod* WellKnownClasses::java_lang_ref_FinalizerReference_add;
-ArtMethod* WellKnownClasses::java_lang_ref_ReferenceQueue_add;
-ArtMethod* WellKnownClasses::java_lang_reflect_InvocationTargetException_init;
-ArtMethod* WellKnownClasses::java_lang_reflect_Parameter_init;
-ArtMethod* WellKnownClasses::java_lang_reflect_Proxy_init;
-ArtMethod* WellKnownClasses::java_lang_reflect_Proxy_invoke;
+ArtMethod* WellKnownClasses::java_lang_NoClassDefFoundError_init;
+ArtMethod* WellKnownClasses::java_lang_OutOfMemoryError_init;
ArtMethod* WellKnownClasses::java_lang_Runtime_nativeLoad;
+ArtMethod* WellKnownClasses::java_lang_RuntimeException_init;
ArtMethod* WellKnownClasses::java_lang_Short_valueOf;
+ArtMethod* WellKnownClasses::java_lang_StackOverflowError_init;
ArtMethod* WellKnownClasses::java_lang_String_charAt;
ArtMethod* WellKnownClasses::java_lang_Thread_dispatchUncaughtException;
ArtMethod* WellKnownClasses::java_lang_Thread_init;
ArtMethod* WellKnownClasses::java_lang_Thread_run;
ArtMethod* WellKnownClasses::java_lang_ThreadGroup_add;
ArtMethod* WellKnownClasses::java_lang_ThreadGroup_threadTerminated;
+ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandle_asType;
+ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact;
+ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandles_lookup;
+ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandles_Lookup_findConstructor;
+ArtMethod* WellKnownClasses::java_lang_ref_FinalizerReference_add;
+ArtMethod* WellKnownClasses::java_lang_ref_ReferenceQueue_add;
+ArtMethod* WellKnownClasses::java_lang_reflect_InvocationTargetException_init;
+ArtMethod* WellKnownClasses::java_lang_reflect_Parameter_init;
+ArtMethod* WellKnownClasses::java_lang_reflect_Proxy_init;
+ArtMethod* WellKnownClasses::java_lang_reflect_Proxy_invoke;
ArtMethod* WellKnownClasses::java_nio_Buffer_isDirect;
ArtMethod* WellKnownClasses::java_nio_DirectByteBuffer_init;
ArtMethod* WellKnownClasses::java_util_function_Consumer_accept;
@@ -318,17 +316,9 @@
CacheClass(env, "dalvik/annotation/optimization/NeverCompile");
dalvik_annotation_optimization_NeverInline =
CacheClass(env, "dalvik/annotation/optimization/NeverInline");
- dalvik_system_EmulatedStackFrame = CacheClass(env, "dalvik/system/EmulatedStackFrame");
java_lang_annotation_Annotation__array = CacheClass(env, "[Ljava/lang/annotation/Annotation;");
- java_lang_Object = CacheClass(env, "java/lang/Object");
- java_lang_OutOfMemoryError = CacheClass(env, "java/lang/OutOfMemoryError");
- java_lang_Error = CacheClass(env, "java/lang/Error");
- java_lang_IllegalAccessError = CacheClass(env, "java/lang/IllegalAccessError");
- java_lang_NoClassDefFoundError = CacheClass(env, "java/lang/NoClassDefFoundError");
java_lang_reflect_Parameter__array = CacheClass(env, "[Ljava/lang/reflect/Parameter;");
- java_lang_RuntimeException = CacheClass(env, "java/lang/RuntimeException");
- java_lang_StackOverflowError = CacheClass(env, "java/lang/StackOverflowError");
java_lang_StringFactory = CacheClass(env, "java/lang/StringFactory");
java_lang_System = CacheClass(env, "java/lang/System");
java_lang_Void = CacheClass(env, "java/lang/Void");
@@ -341,7 +331,7 @@
hiddenapi::ScopedHiddenApiEnforcementPolicySetting hiddenapi_exemption(
hiddenapi::EnforcementPolicy::kDisabled);
- Thread* self = down_cast<JNIEnvExt*>(env)->GetSelf();
+ Thread* self = Thread::ForEnv(env);
ScopedObjectAccess soa(self);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
@@ -362,7 +352,7 @@
java_lang_Short_valueOf =
CachePrimitiveBoxingMethod(class_linker, self, 'S', "Ljava/lang/Short;");
- StackHandleScope<33u> hs(self);
+ StackHandleScope<39u> hs(self);
Handle<mirror::Class> d_s_bdcl =
hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/BaseDexClassLoader;"));
Handle<mirror::Class> d_s_dlcl =
@@ -391,6 +381,18 @@
hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/ClassNotFoundException;"));
Handle<mirror::Class> j_l_Daemons =
hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/Daemons;"));
+ Handle<mirror::Class> j_l_Error =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/Error;"));
+ Handle<mirror::Class> j_l_IllegalAccessError =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/IllegalAccessError;"));
+ Handle<mirror::Class> j_l_NoClassDefFoundError =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/NoClassDefFoundError;"));
+ Handle<mirror::Class> j_l_OutOfMemoryError =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/OutOfMemoryError;"));
+ Handle<mirror::Class> j_l_RuntimeException =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/RuntimeException;"));
+ Handle<mirror::Class> j_l_StackOverflowError =
+ hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/StackOverflowError;"));
Handle<mirror::Class> j_l_Thread =
hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/Thread;"));
Handle<mirror::Class> j_l_tg =
@@ -501,6 +503,19 @@
java_lang_Daemons_waitForDaemonStart = CacheMethod(
j_l_Daemons.Get(), /*is_static=*/ true, "waitForDaemonStart", "()V", pointer_size);
+ java_lang_Error_init = CacheMethod(
+ j_l_Error.Get(), /*is_static=*/ false, "<init>", "()V", pointer_size);
+ java_lang_IllegalAccessError_init = CacheMethod(
+ j_l_IllegalAccessError.Get(), /*is_static=*/ false, "<init>", "()V", pointer_size);
+ java_lang_NoClassDefFoundError_init = CacheMethod(
+ j_l_NoClassDefFoundError.Get(), /*is_static=*/ false, "<init>", "()V", pointer_size);
+ java_lang_OutOfMemoryError_init = CacheMethod(
+ j_l_OutOfMemoryError.Get(), /*is_static=*/ false, "<init>", "()V", pointer_size);
+ java_lang_RuntimeException_init = CacheMethod(
+ j_l_RuntimeException.Get(), /*is_static=*/ false, "<init>", "()V", pointer_size);
+ java_lang_StackOverflowError_init = CacheMethod(
+ j_l_StackOverflowError.Get(), /*is_static=*/ false, "<init>", "()V", pointer_size);
+
ObjPtr<mirror::Class> j_l_String = GetClassRoot<mirror::String>(class_linker);
java_lang_String_charAt = CacheMethod(
j_l_String, /*is_static=*/ false, "charAt", "(I)C", pointer_size);
@@ -715,7 +730,7 @@
// by `CacheMethod()` calling `FindMethodJNI()`.
// TODO: Move this initialization to `ClassLinker`.
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Thread* self = down_cast<JNIEnvExt*>(env)->GetSelf();
+ Thread* self = Thread::ForEnv(env);
ScopedObjectAccess soa(self);
StackHandleScope<1u> hs(self);
Handle<mirror::Class> j_l_Runtime =
@@ -749,16 +764,8 @@
dalvik_annotation_optimization_FastNative = nullptr;
dalvik_annotation_optimization_NeverCompile = nullptr;
dalvik_annotation_optimization_NeverInline = nullptr;
- dalvik_system_EmulatedStackFrame = nullptr;
java_lang_annotation_Annotation__array = nullptr;
- java_lang_Error = nullptr;
- java_lang_IllegalAccessError = nullptr;
- java_lang_NoClassDefFoundError = nullptr;
- java_lang_Object = nullptr;
- java_lang_OutOfMemoryError = nullptr;
java_lang_reflect_Parameter__array = nullptr;
- java_lang_RuntimeException = nullptr;
- java_lang_StackOverflowError = nullptr;
java_lang_StringFactory = nullptr;
java_lang_System = nullptr;
java_lang_Void = nullptr;
@@ -782,28 +789,34 @@
java_lang_Daemons_waitForDaemonStart = nullptr;
java_lang_Double_doubleToRawLongBits = nullptr;
java_lang_Double_valueOf = nullptr;
+ java_lang_Error_init = nullptr;
java_lang_Float_floatToRawIntBits = nullptr;
java_lang_Float_valueOf = nullptr;
+ java_lang_IllegalAccessError_init = nullptr;
java_lang_Integer_valueOf = nullptr;
- java_lang_invoke_MethodHandle_asType = nullptr;
- java_lang_invoke_MethodHandle_invokeExact = nullptr;
- java_lang_invoke_MethodHandles_lookup = nullptr;
- java_lang_invoke_MethodHandles_Lookup_findConstructor = nullptr;
java_lang_Long_valueOf = nullptr;
- java_lang_ref_FinalizerReference_add = nullptr;
- java_lang_ref_ReferenceQueue_add = nullptr;
- java_lang_reflect_InvocationTargetException_init = nullptr;
- java_lang_reflect_Parameter_init = nullptr;
- java_lang_reflect_Proxy_init = nullptr;
- java_lang_reflect_Proxy_invoke = nullptr;
+ java_lang_NoClassDefFoundError_init = nullptr;
+ java_lang_OutOfMemoryError_init = nullptr;
java_lang_Runtime_nativeLoad = nullptr;
+ java_lang_RuntimeException_init = nullptr;
java_lang_Short_valueOf = nullptr;
+ java_lang_StackOverflowError_init = nullptr;
java_lang_String_charAt = nullptr;
java_lang_Thread_dispatchUncaughtException = nullptr;
java_lang_Thread_init = nullptr;
java_lang_Thread_run = nullptr;
java_lang_ThreadGroup_add = nullptr;
java_lang_ThreadGroup_threadTerminated = nullptr;
+ java_lang_invoke_MethodHandle_asType = nullptr;
+ java_lang_invoke_MethodHandle_invokeExact = nullptr;
+ java_lang_invoke_MethodHandles_lookup = nullptr;
+ java_lang_invoke_MethodHandles_Lookup_findConstructor = nullptr;
+ java_lang_ref_FinalizerReference_add = nullptr;
+ java_lang_ref_ReferenceQueue_add = nullptr;
+ java_lang_reflect_InvocationTargetException_init = nullptr;
+ java_lang_reflect_Parameter_init = nullptr;
+ java_lang_reflect_Proxy_init = nullptr;
+ java_lang_reflect_Proxy_invoke = nullptr;
java_nio_Buffer_isDirect = nullptr;
java_nio_DirectByteBuffer_init = nullptr;
libcore_reflect_AnnotationFactory_createAnnotation = nullptr;
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index 56e49db..e8af1c1 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -94,16 +94,8 @@
static jclass dalvik_annotation_optimization_FastNative;
static jclass dalvik_annotation_optimization_NeverCompile;
static jclass dalvik_annotation_optimization_NeverInline;
- static jclass dalvik_system_EmulatedStackFrame;
static jclass java_lang_annotation_Annotation__array;
- static jclass java_lang_Error;
- static jclass java_lang_IllegalAccessError;
- static jclass java_lang_NoClassDefFoundError;
- static jclass java_lang_Object;
- static jclass java_lang_OutOfMemoryError;
static jclass java_lang_reflect_Parameter__array;
- static jclass java_lang_RuntimeException;
- static jclass java_lang_StackOverflowError;
static jclass java_lang_StringFactory;
static jclass java_lang_System;
static jclass java_lang_Void;
@@ -126,28 +118,34 @@
static ArtMethod* java_lang_Daemons_waitForDaemonStart;
static ArtMethod* java_lang_Double_doubleToRawLongBits;
static ArtMethod* java_lang_Double_valueOf;
+ static ArtMethod* java_lang_Error_init; // Only for the declaring class.
static ArtMethod* java_lang_Float_floatToRawIntBits;
static ArtMethod* java_lang_Float_valueOf;
+ static ArtMethod* java_lang_IllegalAccessError_init; // Only for the declaring class.
static ArtMethod* java_lang_Integer_valueOf;
- static ArtMethod* java_lang_invoke_MethodHandle_asType;
- static ArtMethod* java_lang_invoke_MethodHandle_invokeExact;
- static ArtMethod* java_lang_invoke_MethodHandles_lookup;
- static ArtMethod* java_lang_invoke_MethodHandles_Lookup_findConstructor;
static ArtMethod* java_lang_Long_valueOf;
- static ArtMethod* java_lang_ref_FinalizerReference_add;
- static ArtMethod* java_lang_ref_ReferenceQueue_add;
- static ArtMethod* java_lang_reflect_InvocationTargetException_init;
- static ArtMethod* java_lang_reflect_Parameter_init;
- static ArtMethod* java_lang_reflect_Proxy_init;
- static ArtMethod* java_lang_reflect_Proxy_invoke;
+ static ArtMethod* java_lang_NoClassDefFoundError_init; // Only for the declaring class.
+ static ArtMethod* java_lang_OutOfMemoryError_init; // Only for the declaring class.
static ArtMethod* java_lang_Runtime_nativeLoad;
+ static ArtMethod* java_lang_RuntimeException_init; // Only for the declaring class.
static ArtMethod* java_lang_Short_valueOf;
+ static ArtMethod* java_lang_StackOverflowError_init; // Only for the declaring class.
static ArtMethod* java_lang_String_charAt;
static ArtMethod* java_lang_Thread_dispatchUncaughtException;
static ArtMethod* java_lang_Thread_init;
static ArtMethod* java_lang_Thread_run;
static ArtMethod* java_lang_ThreadGroup_add;
static ArtMethod* java_lang_ThreadGroup_threadTerminated;
+ static ArtMethod* java_lang_invoke_MethodHandle_asType;
+ static ArtMethod* java_lang_invoke_MethodHandle_invokeExact;
+ static ArtMethod* java_lang_invoke_MethodHandles_lookup;
+ static ArtMethod* java_lang_invoke_MethodHandles_Lookup_findConstructor;
+ static ArtMethod* java_lang_ref_FinalizerReference_add;
+ static ArtMethod* java_lang_ref_ReferenceQueue_add;
+ static ArtMethod* java_lang_reflect_InvocationTargetException_init;
+ static ArtMethod* java_lang_reflect_Parameter_init;
+ static ArtMethod* java_lang_reflect_Proxy_init;
+ static ArtMethod* java_lang_reflect_Proxy_invoke;
static ArtMethod* java_nio_Buffer_isDirect;
static ArtMethod* java_nio_DirectByteBuffer_init;
static ArtMethod* java_util_function_Consumer_accept;
@@ -219,6 +217,15 @@
static constexpr ClassFromMethod<&java_lang_BootClassLoader_init> java_lang_BootClassLoader;
static constexpr ClassFromField<&java_lang_ClassLoader_parent> java_lang_ClassLoader;
static constexpr ClassFromMethod<&java_lang_Daemons_start> java_lang_Daemons;
+ static constexpr ClassFromMethod<&java_lang_Error_init> java_lang_Error;
+ static constexpr ClassFromMethod<&java_lang_IllegalAccessError_init>
+ java_lang_IllegalAccessError;
+ static constexpr ClassFromMethod<&java_lang_NoClassDefFoundError_init>
+ java_lang_NoClassDefFoundError;
+ static constexpr ClassFromMethod<&java_lang_OutOfMemoryError_init> java_lang_OutOfMemoryError;
+ static constexpr ClassFromMethod<&java_lang_RuntimeException_init> java_lang_RuntimeException;
+ static constexpr ClassFromMethod<&java_lang_StackOverflowError_init>
+ java_lang_StackOverflowError;
static constexpr ClassFromField<&java_lang_Thread_daemon> java_lang_Thread;
static constexpr ClassFromField<&java_lang_ThreadGroup_groups> java_lang_ThreadGroup;
static constexpr ClassFromMethod<&java_lang_reflect_InvocationTargetException_init>
diff --git a/test/051-thread/thread_test.cc b/test/051-thread/thread_test.cc
index 079ad40..33841eb 100644
--- a/test/051-thread/thread_test.cc
+++ b/test/051-thread/thread_test.cc
@@ -22,7 +22,7 @@
extern "C" JNIEXPORT jint JNICALL Java_Main_getNativePriority(JNIEnv* env,
jclass clazz ATTRIBUTE_UNUSED) {
- return ThreadForEnv(env)->GetNativePriority();
+ return Thread::ForEnv(env)->GetNativePriority();
}
extern "C" JNIEXPORT jboolean JNICALL Java_Main_supportsThreadPriorities(