summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2011-09-04 12:01:42 -0700
committerBrian Carlstrom <bdc@google.com>2011-09-04 12:06:58 -0700
commit193a44d9637b51724274b1de384245776e264a46 (patch)
tree198fd6ce98eb1dd2e67e2ea38248b7d3c5abba8f
parent5500cb92a68b87ee1c28977ec0b7734b6b5c1a2f (diff)
downloadart-193a44d9637b51724274b1de384245776e264a46.zip
art-193a44d9637b51724274b1de384245776e264a46.tar.gz
art-193a44d9637b51724274b1de384245776e264a46.tar.bz2
Make InitializeStaticStorageFromCode handle requests for uninitialized storage from <clinit>
Change-Id: I8562ad4fdb33c02c575ddc8986e49ee37c566cfd
-rw-r--r--src/class_linker.cc9
-rw-r--r--src/class_linker_test.cc16
-rw-r--r--test/Statics/Statics.java31
3 files changed, 51 insertions, 5 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 8ddcc5f..7cd320e 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1390,9 +1390,16 @@ StaticStorageBase* ClassLinker::InitializeStaticStorageFromCode(uint32_t type_id
if (klass == NULL) {
UNIMPLEMENTED(FATAL) << "throw exception due to unresolved class";
}
+ // If we are the <clinit> of this class, just return our storage.
+ //
+ // Do not set the DexCache InitializedStaticStorage, since that
+ // implies <clinit> has finished running.
+ if (klass == referrer->GetDeclaringClass() && referrer->GetName()->Equals("<clinit>")) {
+ return klass;
+ }
if (!class_linker->EnsureInitialized(klass)) {
CHECK(Thread::Current()->IsExceptionPending());
- UNIMPLEMENTED(FATAL) << "throw exception due to class initializtion problem";
+ UNIMPLEMENTED(FATAL) << "throw exception due to class initialization problem";
}
referrer->GetDexCacheInitializedStaticStorage()->Set(type_idx, klass);
return klass;
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 92b3fca..d30f4bf 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -566,19 +566,27 @@ TEST_F(ClassLinkerTest, Interfaces) {
}
TEST_F(ClassLinkerTest, InitializeStaticStorageFromCode) {
- // pretend we are trying to ensure we have initilized storage for Static from Statics.<clinit>
+ // pretend we are trying to get the static storage for the Statics class.
+
+ // case 1, get the uninitialized storage from Statics.<clinit>
+ // case 2, get the initialized storage from Statics.getS8
+
const ClassLoader* class_loader = LoadDex("Statics");
const DexFile* dex_file = ClassLoader::GetClassPath(class_loader)[0];
CHECK(dex_file != NULL);
Class* Statics = class_linker_->FindClass("LStatics;", class_loader);
Method* clinit = Statics->FindDirectMethod("<clinit>", "()V");
+ Method* getS8 = Statics->FindDirectMethod("getS8", "()Ljava/lang/Object;");
uint32_t type_idx = FindTypeIdxByDescriptor(*dex_file, "LStatics;");
EXPECT_TRUE(clinit->GetDexCacheInitializedStaticStorage()->Get(type_idx) == NULL);
- StaticStorageBase* storage = class_linker_->InitializeStaticStorageFromCode(type_idx, clinit);
- EXPECT_TRUE(storage != NULL);
- EXPECT_EQ(storage, clinit->GetDexCacheInitializedStaticStorage()->Get(type_idx));
+ StaticStorageBase* uninit = class_linker_->InitializeStaticStorageFromCode(type_idx, clinit);
+ EXPECT_TRUE(uninit != NULL);
+ EXPECT_TRUE(clinit->GetDexCacheInitializedStaticStorage()->Get(type_idx) == NULL);
+ StaticStorageBase* init = class_linker_->InitializeStaticStorageFromCode(type_idx, getS8);
+ EXPECT_TRUE(init != NULL);
+ EXPECT_EQ(init, clinit->GetDexCacheInitializedStaticStorage()->Get(type_idx));
}
} // namespace art
diff --git a/test/Statics/Statics.java b/test/Statics/Statics.java
index c38447b..b777650 100644
--- a/test/Statics/Statics.java
+++ b/test/Statics/Statics.java
@@ -11,4 +11,35 @@ class Statics {
static double s7 = 16777217;
static Object s8 = "android";
static Object[] s9 = { "a", "b" };
+
+ static boolean getS0() {
+ return s0;
+ }
+ static byte getS1() {
+ return s1;
+ }
+ static char getS2() {
+ return s2;
+ }
+ static short getS3() {
+ return s3;
+ }
+ static int getS4() {
+ return s4;
+ }
+ static long getS5() {
+ return s5;
+ }
+ static float getS6() {
+ return s6;
+ }
+ static double getS7() {
+ return s7;
+ }
+ static Object getS8() {
+ return s8;
+ }
+ static Object[] getS9() {
+ return s9;
+ }
}