Remove intialized static storage from dex cache.

The initialized static storage array is used by compiled code to determine if
for a sget/sput class initialization is necessary. The compiled code typically
doesn't require this test as the class is pre-initialized or the class being
accessed is the same as the current method.

Change-Id: Icbc45e692b3d0ac61e559e69edb6c9b29439e571
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index e9bbf91..06c7b53 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -39,7 +39,7 @@
 #define STRING_DATA_OFFSET 12
 
 // Offsets within java.lang.Method.
-#define METHOD_DEX_CACHE_METHODS_OFFSET 16
-#define METHOD_CODE_OFFSET 40
+#define METHOD_DEX_CACHE_METHODS_OFFSET 12
+#define METHOD_CODE_OFFSET 36
 
 #endif  // ART_RUNTIME_ASM_SUPPORT_H_
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index fbb47bd..dcc50b7 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1242,15 +1242,8 @@
   if (fields.get() == NULL) {
     return NULL;
   }
-  SirtRef<mirror::ObjectArray<mirror::StaticStorageBase> >
-      initialized_static_storage(self,
-                          AllocObjectArray<mirror::StaticStorageBase>(self, dex_file.NumTypeIds()));
-  if (initialized_static_storage.get() == NULL) {
-    return NULL;
-  }
-
   dex_cache->Init(&dex_file, location.get(), strings.get(), types.get(), methods.get(),
-                  fields.get(), initialized_static_storage.get());
+                  fields.get());
   return dex_cache.get();
 }
 
@@ -1905,7 +1898,6 @@
   dst->SetDexCacheStrings(klass->GetDexCache()->GetStrings());
   dst->SetDexCacheResolvedMethods(klass->GetDexCache()->GetResolvedMethods());
   dst->SetDexCacheResolvedTypes(klass->GetDexCache()->GetResolvedTypes());
-  dst->SetDexCacheInitializedStaticStorage(klass->GetDexCache()->GetInitializedStaticStorage());
 
   uint32_t access_flags = it.GetMemberAccessFlags();
 
@@ -2941,8 +2933,6 @@
   CHECK_EQ(prototype->GetDexCacheStrings(), method->GetDexCacheStrings());
   CHECK_EQ(prototype->GetDexCacheResolvedMethods(), method->GetDexCacheResolvedMethods());
   CHECK_EQ(prototype->GetDexCacheResolvedTypes(), method->GetDexCacheResolvedTypes());
-  CHECK_EQ(prototype->GetDexCacheInitializedStaticStorage(),
-           method->GetDexCacheInitializedStaticStorage());
   CHECK_EQ(prototype->GetDexMethodIndex(), method->GetDexMethodIndex());
 
   MethodHelper mh(method);
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 34134fa..1744050 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -159,15 +159,12 @@
     EXPECT_TRUE(method->GetDexCacheStrings() != NULL);
     EXPECT_TRUE(method->GetDexCacheResolvedMethods() != NULL);
     EXPECT_TRUE(method->GetDexCacheResolvedTypes() != NULL);
-    EXPECT_TRUE(method->GetDexCacheInitializedStaticStorage() != NULL);
     EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetStrings(),
               method->GetDexCacheStrings());
     EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetResolvedMethods(),
               method->GetDexCacheResolvedMethods());
     EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetResolvedTypes(),
               method->GetDexCacheResolvedTypes());
-    EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetInitializedStaticStorage(),
-              method->GetDexCacheInitializedStaticStorage());
   }
 
   void AssertField(mirror::Class* klass, mirror::ArtField* field)
@@ -468,7 +465,6 @@
   ArtMethodOffsets() : CheckOffsets<mirror::ArtMethod>(false, "Ljava/lang/reflect/ArtMethod;") {
     // alphabetical references
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, declaring_class_),                      "declaringClass"));
-    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, dex_cache_initialized_static_storage_), "dexCacheInitializedStaticStorage"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, dex_cache_resolved_methods_),           "dexCacheResolvedMethods"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, dex_cache_resolved_types_),             "dexCacheResolvedTypes"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, dex_cache_strings_),                    "dexCacheStrings"));
@@ -607,7 +603,6 @@
   DexCacheOffsets() : CheckOffsets<mirror::DexCache>(false, "Ljava/lang/DexCache;") {
     // alphabetical references
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, dex_),                        "dex"));
-    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, initialized_static_storage_), "initializedStaticStorage"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, location_),                   "location"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_fields_),            "resolvedFields"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_methods_),           "resolvedMethods"));
@@ -1006,13 +1001,12 @@
   const DexFile::TypeId* type_id = dex_file->FindTypeId(dex_file->GetIndexForStringId(*string_id));
   ASSERT_TRUE(type_id != NULL);
   uint32_t type_idx = dex_file->GetIndexForTypeId(*type_id);
-  EXPECT_TRUE(clinit->GetDexCacheInitializedStaticStorage()->Get(type_idx) == NULL);
-  mirror::StaticStorageBase* uninit = ResolveVerifyAndClinit(type_idx, clinit, Thread::Current(), true, false);
+  mirror::Class* uninit = ResolveVerifyAndClinit(type_idx, clinit, Thread::Current(), true, false);
   EXPECT_TRUE(uninit != NULL);
-  EXPECT_TRUE(clinit->GetDexCacheInitializedStaticStorage()->Get(type_idx) == NULL);
-  mirror::StaticStorageBase* init = ResolveVerifyAndClinit(type_idx, getS0, Thread::Current(), true, false);
+  EXPECT_FALSE(uninit->IsInitialized());
+  mirror::Class* init = ResolveVerifyAndClinit(type_idx, getS0, Thread::Current(), true, false);
   EXPECT_TRUE(init != NULL);
-  EXPECT_EQ(init, clinit->GetDexCacheInitializedStaticStorage()->Get(type_idx));
+  EXPECT_TRUE(init->IsInitialized());
 }
 
 TEST_F(ClassLinkerTest, FinalizableBit) {
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index a60446c..e7fe072 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -517,15 +517,15 @@
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   mirror::Class* klass = class_linker->ResolveType(type_idx, referrer);
-  if (UNLIKELY(klass == NULL)) {
+  if (UNLIKELY(klass == nullptr)) {
     CHECK(self->IsExceptionPending());
-    return NULL;  // Failure - Indicate to caller to deliver exception
+    return nullptr;  // Failure - Indicate to caller to deliver exception
   }
   // Perform access check if necessary.
   mirror::Class* referring_class = referrer->GetDeclaringClass();
   if (verify_access && UNLIKELY(!referring_class->CanAccess(klass))) {
     ThrowIllegalAccessErrorClass(referring_class, klass);
-    return NULL;  // Failure - Indicate to caller to deliver exception
+    return nullptr;  // Failure - Indicate to caller to deliver exception
   }
   // If we're just implementing const-class, we shouldn't call <clinit>.
   if (!can_run_clinit) {
@@ -541,9 +541,8 @@
   SirtRef<mirror::Class> sirt_class(self, klass);
   if (!class_linker->EnsureInitialized(sirt_class, true, true)) {
     CHECK(self->IsExceptionPending());
-    return NULL;  // Failure - Indicate to caller to deliver exception
+    return nullptr;  // Failure - Indicate to caller to deliver exception
   }
-  referrer->GetDexCacheInitializedStaticStorage()->Set(type_idx, sirt_class.get());
   return sirt_class.get();
 }
 
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index c9bf160..088f616 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -73,12 +73,6 @@
       OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_), false);
 }
 
-inline ObjectArray<StaticStorageBase>* ArtMethod::GetDexCacheInitializedStaticStorage() const {
-  return GetFieldObject<ObjectArray<StaticStorageBase>*>(
-      OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_initialized_static_storage_),
-      false);
-}
-
 inline uint32_t ArtMethod::GetCodeSize() const {
   DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this);
   uintptr_t code = reinterpret_cast<uintptr_t>(GetEntryPointFromCompiledCode());
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index a4f6b3b..f4a076c 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -86,11 +86,6 @@
                  new_dex_cache_classes, false);
 }
 
-void ArtMethod::SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value) {
-  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_initialized_static_storage_),
-      new_value, false);
-}
-
 size_t ArtMethod::NumArgRegisters(const StringPiece& shorty) {
   CHECK_LE(1, shorty.length());
   uint32_t num_registers = 0;
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index d5524ec..963b4d5 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -184,11 +184,6 @@
     return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_);
   }
 
-  static MemberOffset DexCacheInitializedStaticStorageOffset() {
-    return OFFSET_OF_OBJECT_MEMBER(ArtMethod,
-        dex_cache_initialized_static_storage_);
-  }
-
   ObjectArray<ArtMethod>* GetDexCacheResolvedMethods() const;
   void SetDexCacheResolvedMethods(ObjectArray<ArtMethod>* new_dex_cache_methods)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -197,10 +192,6 @@
   void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  ObjectArray<StaticStorageBase>* GetDexCacheInitializedStaticStorage() const;
-  void SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
   // Find the method that this method overrides
   ArtMethod* FindOverriddenMethod() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
@@ -391,9 +382,6 @@
   Class* declaring_class_;
 
   // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
-  ObjectArray<StaticStorageBase>* dex_cache_initialized_static_storage_;
-
-  // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
   ObjectArray<ArtMethod>* dex_cache_resolved_methods_;
 
   // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 50ede66..9aa23d9 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -70,15 +70,8 @@
 class DexCache;
 class IfTable;
 
-// Type for the InitializedStaticStorage table. Currently the Class
-// provides the static storage. However, this might change to an Array
-// to improve image sharing, so we use this type to avoid assumptions
-// on the current storage.
-class MANAGED StaticStorageBase : public Object {
-};
-
 // C++ mirror of java.lang.Class
-class MANAGED Class : public StaticStorageBase {
+class MANAGED Class : public Object {
  public:
   // Class Status
   //
@@ -133,6 +126,10 @@
 
   void SetStatus(Status new_status, Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  static MemberOffset StatusOffset() {
+    return OFFSET_OF_OBJECT_MEMBER(Class, status_);
+  }
+
   // Returns true if the class has failed to link.
   bool IsErroneous() const {
     return GetStatus() == kStatusError;
diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc
index 00531e3..fa0900c 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -36,15 +36,13 @@
                     ObjectArray<String>* strings,
                     ObjectArray<Class>* resolved_types,
                     ObjectArray<ArtMethod>* resolved_methods,
-                    ObjectArray<ArtField>* resolved_fields,
-                    ObjectArray<StaticStorageBase>* initialized_static_storage) {
-  CHECK(dex_file != NULL);
-  CHECK(location != NULL);
-  CHECK(strings != NULL);
-  CHECK(resolved_types != NULL);
-  CHECK(resolved_methods != NULL);
-  CHECK(resolved_fields != NULL);
-  CHECK(initialized_static_storage != NULL);
+                    ObjectArray<ArtField>* resolved_fields) {
+  CHECK(dex_file != nullptr);
+  CHECK(location != nullptr);
+  CHECK(strings != nullptr);
+  CHECK(resolved_types != nullptr);
+  CHECK(resolved_methods != nullptr);
+  CHECK(resolved_fields != nullptr);
 
   SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file, false);
   SetFieldObject(OFFSET_OF_OBJECT_MEMBER(DexCache, location_), location, false);
@@ -52,8 +50,6 @@
   SetFieldObject(OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_), resolved_types, false);
   SetFieldObject(ResolvedMethodsOffset(), resolved_methods, false);
   SetFieldObject(ResolvedFieldsOffset(), resolved_fields, false);
-  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(DexCache, initialized_static_storage_),
-                 initialized_static_storage, false);
 
   Runtime* runtime = Runtime::Current();
   if (runtime->HasResolutionMethod()) {
@@ -68,11 +64,11 @@
 
 void DexCache::Fixup(ArtMethod* trampoline) {
   // Fixup the resolve methods array to contain trampoline for resolution.
-  CHECK(trampoline != NULL);
+  CHECK(trampoline != nullptr);
   ObjectArray<ArtMethod>* resolved_methods = GetResolvedMethods();
   size_t length = resolved_methods->GetLength();
   for (size_t i = 0; i < length; i++) {
-    if (resolved_methods->GetWithoutChecks(i) == NULL) {
+    if (resolved_methods->GetWithoutChecks(i) == nullptr) {
       resolved_methods->SetWithoutChecks(i, trampoline);
     }
   }
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 0522f13..a5fe598 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -47,8 +47,7 @@
             ObjectArray<String>* strings,
             ObjectArray<Class>* types,
             ObjectArray<ArtMethod>* methods,
-            ObjectArray<ArtField>* fields,
-            ObjectArray<StaticStorageBase>* initialized_static_storage)
+            ObjectArray<ArtField>* fields)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   void Fixup(ArtMethod* trampoline) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -85,11 +84,6 @@
     return GetResolvedFields()->GetLength();
   }
 
-  size_t NumInitializedStaticStorage() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return GetInitializedStaticStorage()->GetLength();
-  }
-
   String* GetResolvedString(uint32_t string_idx) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return GetStrings()->Get(string_idx);
@@ -149,12 +143,6 @@
     return GetFieldObject< ObjectArray<ArtField>* >(ResolvedFieldsOffset(), false);
   }
 
-  ObjectArray<StaticStorageBase>* GetInitializedStaticStorage() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return GetFieldObject< ObjectArray<StaticStorageBase>* >(
-        OFFSET_OF_OBJECT_MEMBER(DexCache, initialized_static_storage_), false);
-  }
-
   const DexFile* GetDexFile() const {
     return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), false);
   }
@@ -165,7 +153,6 @@
 
  private:
   Object* dex_;
-  ObjectArray<StaticStorageBase>* initialized_static_storage_;
   String* location_;
   ObjectArray<ArtField>* resolved_fields_;
   ObjectArray<ArtMethod>* resolved_methods_;
diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc
index 441c6da..6bed224 100644
--- a/runtime/mirror/dex_cache_test.cc
+++ b/runtime/mirror/dex_cache_test.cc
@@ -39,13 +39,11 @@
   EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),   dex_cache->NumResolvedTypes());
   EXPECT_EQ(java_lang_dex_file_->NumMethodIds(), dex_cache->NumResolvedMethods());
   EXPECT_EQ(java_lang_dex_file_->NumFieldIds(),  dex_cache->NumResolvedFields());
-  EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),   dex_cache->NumInitializedStaticStorage());
 
   EXPECT_LE(0, dex_cache->GetStrings()->GetLength());
   EXPECT_LE(0, dex_cache->GetResolvedTypes()->GetLength());
   EXPECT_LE(0, dex_cache->GetResolvedMethods()->GetLength());
   EXPECT_LE(0, dex_cache->GetResolvedFields()->GetLength());
-  EXPECT_LE(0, dex_cache->GetInitializedStaticStorage()->GetLength());
 
   EXPECT_EQ(java_lang_dex_file_->NumStringIds(),
             static_cast<uint32_t>(dex_cache->GetStrings()->GetLength()));
@@ -55,8 +53,6 @@
             static_cast<uint32_t>(dex_cache->GetResolvedMethods()->GetLength()));
   EXPECT_EQ(java_lang_dex_file_->NumFieldIds(),
             static_cast<uint32_t>(dex_cache->GetResolvedFields()->GetLength()));
-  EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),
-            static_cast<uint32_t>(dex_cache->GetInitializedStaticStorage()->GetLength()));
 }
 
 }  // namespace mirror
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 726a8f1..6f30cc9 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -234,7 +234,6 @@
     return;
   }
   // LOG(INFO) << "VMRuntime.preloadDexCaches static storage klass=" << class_name;
-  dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass);
 }
 
 // Based on ClassLinker::ResolveField.
@@ -306,12 +305,10 @@
     uint32_t num_types;
     uint32_t num_fields;
     uint32_t num_methods;
-    uint32_t num_static_storage;
     DexCacheStats() : num_strings(0),
                       num_types(0),
                       num_fields(0),
-                      num_methods(0),
-                      num_static_storage(0) {}
+                      num_methods(0) {}
 };
 
 static const bool kPreloadDexCachesEnabled = true;
@@ -339,7 +336,6 @@
     total->num_fields += dex_file->NumFieldIds();
     total->num_methods += dex_file->NumMethodIds();
     total->num_types += dex_file->NumTypeIds();
-    total->num_static_storage += dex_file->NumTypeIds();
   }
 }
 
@@ -378,12 +374,6 @@
         filled->num_methods++;
       }
     }
-    for (size_t i = 0; i < dex_cache->NumInitializedStaticStorage(); i++) {
-      mirror::StaticStorageBase* klass = dex_cache->GetInitializedStaticStorage()->Get(i);
-      if (klass != NULL) {
-        filled->num_static_storage++;
-      }
-    }
   }
 }
 
@@ -477,10 +467,6 @@
                               total.num_fields, before.num_fields, after.num_fields);
     LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches methods total=%d before=%d after=%d",
                               total.num_methods, before.num_methods, after.num_methods);
-    LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches storage total=%d before=%d after=%d",
-                              total.num_static_storage,
-                              before.num_static_storage,
-                              after.num_static_storage);
     LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches finished");
   }
 }
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 52e74ab..caf18f1 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -22,7 +22,7 @@
 namespace art {
 
 const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
-const uint8_t OatHeader::kOatVersion[] = { '0', '1', '2', '\0' };
+const uint8_t OatHeader::kOatVersion[] = { '0', '1', '3', '\0' };
 
 OatHeader::OatHeader() {
   memset(this, 0, sizeof(*this));