diff options
-rw-r--r-- | src/class_linker.cc | 7 | ||||
-rw-r--r-- | src/class_linker.h | 1 | ||||
-rw-r--r-- | src/object.cc | 14 | ||||
-rw-r--r-- | src/object.h | 11 | ||||
-rw-r--r-- | src/runtime.cc | 3 | ||||
-rw-r--r-- | src/thread.cc | 6 |
6 files changed, 36 insertions, 6 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index 6f1e5aa..cf0c094 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -186,6 +186,7 @@ const char* ClassLinker::class_roots_descriptors_[] = { "Ljava/lang/ClassLoader;", "Ldalvik/system/BaseDexClassLoader;", "Ldalvik/system/PathClassLoader;", + "Ljava/lang/Throwable;", "Ljava/lang/StackTraceElement;", "Z", "B", @@ -470,7 +471,9 @@ void ClassLinker::Init(const std::string& boot_class_path) { SetClassRoot(kDalvikSystemPathClassLoader, dalvik_system_PathClassLoader); PathClassLoader::SetClass(dalvik_system_PathClassLoader); - // Set up java.lang.StackTraceElement as a convenience + // Set up java.lang.Throwable and java.lang.StackTraceElement as a convenience + SetClassRoot(kJavaLangThrowable, FindSystemClass("Ljava/lang/Throwable;")); + Throwable::SetClass(GetClassRoot(kJavaLangThrowable)); SetClassRoot(kJavaLangStackTraceElement, FindSystemClass("Ljava/lang/StackTraceElement;")); SetClassRoot(kJavaLangStackTraceElementArrayClass, FindSystemClass("[Ljava/lang/StackTraceElement;")); StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement)); @@ -933,6 +936,7 @@ void ClassLinker::InitFromImage() { LongArray::SetArrayClass(GetClassRoot(kLongArrayClass)); ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass)); PathClassLoader::SetClass(GetClassRoot(kDalvikSystemPathClassLoader)); + Throwable::SetClass(GetClassRoot(kJavaLangThrowable)); StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement)); FinishInit(); @@ -1009,6 +1013,7 @@ ClassLinker::~ClassLinker() { LongArray::ResetArrayClass(); ShortArray::ResetArrayClass(); PathClassLoader::ResetClass(); + Throwable::ResetClass(); StackTraceElement::ResetClass(); STLDeleteElements(&boot_class_path_); STLDeleteElements(&oat_files_); diff --git a/src/class_linker.h b/src/class_linker.h index 10d8305..f2b44a3 100644 --- a/src/class_linker.h +++ b/src/class_linker.h @@ -429,6 +429,7 @@ class ClassLinker { kJavaLangClassLoader, kDalvikSystemBaseDexClassLoader, kDalvikSystemPathClassLoader, + kJavaLangThrowable, kJavaLangStackTraceElement, kPrimitiveBoolean, kPrimitiveByte, diff --git a/src/object.cc b/src/object.cc index f90031a..9e3e9d3 100644 --- a/src/object.cc +++ b/src/object.cc @@ -1382,6 +1382,20 @@ std::string Throwable::Dump() const { return result; } + +Class* Throwable::java_lang_Throwable_ = NULL; + +void Throwable::SetClass(Class* java_lang_Throwable) { + CHECK(java_lang_Throwable_ == NULL); + CHECK(java_lang_Throwable != NULL); + java_lang_Throwable_ = java_lang_Throwable; +} + +void Throwable::ResetClass() { + CHECK(java_lang_Throwable_ != NULL); + java_lang_Throwable_ = NULL; +} + Class* StackTraceElement::java_lang_StackTraceElement_ = NULL; void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) { diff --git a/src/object.h b/src/object.h index e9556ef..c2f8cc1 100644 --- a/src/object.h +++ b/src/object.h @@ -2278,6 +2278,15 @@ class MANAGED Throwable : public Object { // in cases like the verifier where the checks cannot fail and initCause isn't overridden. void SetCause(Throwable* cause); bool IsCheckedException() const; + + static Class* GetJavaLangThrowable() { + DCHECK(java_lang_Throwable_ != NULL); + return java_lang_Throwable_; + } + + static void SetClass(Class* java_lang_Throwable); + static void ResetClass(); + private: Object* GetStackState() const { return GetFieldObject<Object*>(OFFSET_OF_OBJECT_MEMBER(Throwable, stack_state_), true); @@ -2290,6 +2299,8 @@ class MANAGED Throwable : public Object { Object* stack_trace_; Object* suppressed_exceptions_; + static Class* java_lang_Throwable_; + friend struct ThrowableOffsets; // for verifying offset information DISALLOW_IMPLICIT_CONSTRUCTORS(Throwable); }; diff --git a/src/runtime.cc b/src/runtime.cc index d7b0d15..579e591 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -650,6 +650,8 @@ void Runtime::InitNativeMethods() { void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) { #define REGISTER(FN) extern void FN(JNIEnv*); FN(env) + // Register Throwable first so that registration of other native methods can throw exceptions + REGISTER(register_java_lang_Throwable); REGISTER(register_dalvik_system_DexFile); REGISTER(register_dalvik_system_VMDebug); REGISTER(register_dalvik_system_VMRuntime); @@ -661,7 +663,6 @@ void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) { REGISTER(register_java_lang_String); REGISTER(register_java_lang_System); REGISTER(register_java_lang_Thread); - REGISTER(register_java_lang_Throwable); REGISTER(register_java_lang_VMClassLoader); REGISTER(register_java_lang_reflect_Array); REGISTER(register_java_lang_reflect_Constructor); diff --git a/src/thread.cc b/src/thread.cc index 7113655..54b17d0 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -54,7 +54,6 @@ namespace art { pthread_key_t Thread::pthread_key_self_; static Class* gThreadLock = NULL; -static Class* gThrowable = NULL; static Field* gThread_daemon = NULL; static Field* gThread_group = NULL; static Field* gThread_lock = NULL; @@ -739,7 +738,6 @@ void Thread::FinishStartup() { Class* ThreadGroup_class = FindClassOrDie(class_linker, "Ljava/lang/ThreadGroup;"); Class* UncaughtExceptionHandler_class = FindClassOrDie(class_linker, "Ljava/lang/Thread$UncaughtExceptionHandler;"); gThreadLock = FindClassOrDie(class_linker, "Ljava/lang/ThreadLock;"); - gThrowable = FindClassOrDie(class_linker, "Ljava/lang/Throwable;"); gThread_daemon = FindFieldOrDie(Thread_class, "daemon", "Z"); gThread_group = FindFieldOrDie(Thread_class, "group", "Ljava/lang/ThreadGroup;"); @@ -1001,8 +999,8 @@ class CountStackDepthVisitor : public Thread::StackVisitor { // We want to skip frames up to and including the exception's constructor. // Note we also skip the frame if it doesn't have a method (namely the callee // save frame) - DCHECK(gThrowable != NULL); - if (skipping_ && frame.HasMethod() && !gThrowable->IsAssignableFrom(frame.GetMethod()->GetDeclaringClass())) { + if (skipping_ && frame.HasMethod() && + !Throwable::GetJavaLangThrowable()->IsAssignableFrom(frame.GetMethod()->GetDeclaringClass())) { skipping_ = false; } if (!skipping_) { |