summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/class_linker.cc7
-rw-r--r--src/class_linker.h1
-rw-r--r--src/object.cc14
-rw-r--r--src/object.h11
-rw-r--r--src/runtime.cc3
-rw-r--r--src/thread.cc6
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_) {