diff options
author | 2014-02-19 15:21:21 -0800 | |
---|---|---|
committer | 2014-02-19 15:53:35 -0800 | |
commit | 073278cd7129ff07dbcd6ccfabd2c34f47ec92ad (patch) | |
tree | c8dbc60d903653ecde81cef4d781128884859374 | |
parent | a3537fb03e092a82f08ceb670a2eafa703203465 (diff) |
Do not FixupStaticTrampolines of uninitialized classes
Bug: 13027732
Change-Id: I5966d63afd8fbcd091801297290f117f3c9cb44c
-rw-r--r-- | runtime/class_linker.cc | 6 | ||||
-rw-r--r-- | runtime/mirror/class-inl.h | 2 | ||||
-rw-r--r-- | test/084-class-init/expected.txt | 2 | ||||
-rw-r--r-- | test/084-class-init/src/Main.java | 30 |
4 files changed, 36 insertions, 4 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index f8a20d0617..fa50324c51 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1684,6 +1684,7 @@ static bool NeedsInterpreter(mirror::ArtMethod* method, const void* quick_code, } void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { + DCHECK(klass->IsInitialized()) << PrettyDescriptor(klass); if (klass->NumDirectMethods() == 0) { return; // No direct methods => no static methods. } @@ -3159,9 +3160,6 @@ bool ClassLinker::InitializeClass(const SirtRef<mirror::Class>& klass, bool can_ } } - // Opportunistically set static method trampolines to their destination. - FixupStaticTrampolines(klass.get()); - uint64_t t1 = NanoTime(); bool success = true; @@ -3185,6 +3183,8 @@ bool ClassLinker::InitializeClass(const SirtRef<mirror::Class>& klass, bool can_ ClassHelper kh(klass.get()); LOG(INFO) << "Initialized class " << kh.GetDescriptor() << " from " << kh.GetLocation(); } + // Opportunistically set static method trampolines to their destination. + FixupStaticTrampolines(klass.get()); } } return success; diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 4c2bdb02dd..cba221d01f 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -41,7 +41,7 @@ inline uint32_t Class::GetObjectSize() { inline Class* Class::GetSuperClass() { // Can only get super class for loaded classes (hack for when runtime is // initializing) - DCHECK(IsLoaded() || !Runtime::Current()->IsStarted()) << IsLoaded(); + DCHECK(IsLoaded() || IsErroneous() || !Runtime::Current()->IsStarted()) << IsLoaded(); return GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), false); } diff --git a/test/084-class-init/expected.txt b/test/084-class-init/expected.txt index 13892147c2..d7a80bf741 100644 --- a/test/084-class-init/expected.txt +++ b/test/084-class-init/expected.txt @@ -8,3 +8,5 @@ SlowInit static block post-sleep MethodThread message Fields (child thread): 111222333444 Fields (main thread): 111222333444 +checkStaticMethodInvokeAfterFailedClinit START +checkStaticMethodInvokeAfterFailedClinit PASSED diff --git a/test/084-class-init/src/Main.java b/test/084-class-init/src/Main.java index cf69570854..28eb3e923f 100644 --- a/test/084-class-init/src/Main.java +++ b/test/084-class-init/src/Main.java @@ -37,6 +37,7 @@ public class Main { public static void main(String[] args) { checkExceptions(); checkTiming(); + checkStaticMethodInvokeAfterFailedClinit(); } public static void sleep(int msec) { @@ -128,4 +129,33 @@ public class Main { SlowInit.printMsg("MethodThread message"); } } + + static void checkStaticMethodInvokeAfterFailedClinit() { + System.out.println("checkStaticMethodInvokeAfterFailedClinit START"); + + // Call static method to cause implicit clinit. + try { + ClassWithThrowingClinit.staticMethod(); + System.out.println("checkStaticMethodInvokeAfterFailedClinit FAILED" + + " due to missing ExceptionInInitializerError"); + } catch (ExceptionInInitializerError expected) { + } + + // Call again to make sure we still get the expected error. + try { + ClassWithThrowingClinit.staticMethod(); + System.out.println("checkStaticMethodInvokeAfterFailedClinit FAILED" + + " due to missing NoClassDefFoundError"); + } catch (NoClassDefFoundError expected) { + } + System.out.println("checkStaticMethodInvokeAfterFailedClinit PASSED"); + } + + static class ClassWithThrowingClinit { + static { + throwDuringClinit(); + } + static void staticMethod() { + } + } } |