Add InitializedStaticStorage table
A non-null entry in the table not only provides access to the storage,
it also implies that the referenced type is initialized.
Change-Id: Ief9e88b7e58b65b6f9456a4218b7fe87f71c17bb
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 41a1c55..8236739 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -434,7 +434,8 @@
AllocObjectArray<Class>(dex_file.NumTypeIds()),
AllocObjectArray<Method>(dex_file.NumMethodIds()),
AllocObjectArray<Field>(dex_file.NumFieldIds()),
- AllocCodeAndDirectMethods(dex_file.NumMethodIds()));
+ AllocCodeAndDirectMethods(dex_file.NumMethodIds()),
+ AllocObjectArray<StaticStorageBase>(dex_file.NumTypeIds()));
return dex_cache;
}
@@ -767,10 +768,11 @@
dst->access_flags_ = src.access_flags_;
dst->dex_cache_strings_ = klass->dex_cache_->GetStrings();
- dst->dex_cache_types_ = klass->dex_cache_->GetTypes();
- dst->dex_cache_methods_ = klass->dex_cache_->GetMethods();
- dst->dex_cache_fields_ = klass->dex_cache_->GetFields();
+ dst->dex_cache_resolved_types_ = klass->dex_cache_->GetResolvedTypes();
+ dst->dex_cache_resolved_methods_ = klass->dex_cache_->GetResolvedMethods();
+ dst->dex_cache_resolved_fields_ = klass->dex_cache_->GetResolvedFields();
dst->dex_cache_code_and_direct_methods_ = klass->dex_cache_->GetCodeAndDirectMethods();
+ dst->dex_cache_initialized_static_storage_ = klass->dex_cache_->GetInitializedStaticStorage();
dst->is_direct_ = is_direct;
@@ -1277,6 +1279,19 @@
return !Thread::Current()->IsExceptionPending();
}
+StaticStorageBase* ClassLinker::InitializeStaticStorageFromCode(uint32_t type_idx, Method* referrer) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ Class* klass = class_linker->ResolveType(type_idx, referrer);
+ if (klass == NULL) {
+ UNIMPLEMENTED(FATAL) << "throw exception due to unresolved class";
+ }
+ if (!class_linker->EnsureInitialized(klass)) {
+ CHECK(Thread::Current()->IsExceptionPending());
+ UNIMPLEMENTED(FATAL) << "throw exception due to class initializtion problem";
+ }
+ return klass;
+}
+
void ClassLinker::InitializeStaticFields(Class* klass) {
size_t num_static_fields = klass->NumStaticFields();
if (num_static_fields == 0) {
diff --git a/src/class_linker.h b/src/class_linker.h
index 5e3ac78..d9716ee 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -78,6 +78,8 @@
DexCache* dex_cache,
const ClassLoader* class_loader);
+ static StaticStorageBase* InitializeStaticStorageFromCode(uint32_t type_idx, Method* referrer);
+
// Resolve a method with a given ID from the DexFile, storing the
// result in DexCache. The ClassLinker and ClassLoader are used as
// in ResolveType. What is unique is the method type argument which
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 9fd5fb5..8de8ba1 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -102,16 +102,23 @@
EXPECT_TRUE(method->GetSignature() != NULL);
EXPECT_TRUE(method->dex_cache_strings_ != NULL);
- EXPECT_TRUE(method->dex_cache_types_ != NULL);
- EXPECT_TRUE(method->dex_cache_methods_ != NULL);
- EXPECT_TRUE(method->dex_cache_fields_ != NULL);
+ EXPECT_TRUE(method->dex_cache_resolved_types_ != NULL);
+ EXPECT_TRUE(method->dex_cache_resolved_methods_ != NULL);
+ EXPECT_TRUE(method->dex_cache_resolved_fields_ != NULL);
EXPECT_TRUE(method->dex_cache_code_and_direct_methods_ != NULL);
- EXPECT_EQ(method->declaring_class_->dex_cache_->GetStrings(), method->dex_cache_strings_);
- EXPECT_EQ(method->declaring_class_->dex_cache_->GetTypes(), method->dex_cache_types_);
- EXPECT_EQ(method->declaring_class_->dex_cache_->GetMethods(), method->dex_cache_methods_);
- EXPECT_EQ(method->declaring_class_->dex_cache_->GetFields(), method->dex_cache_fields_);
+ EXPECT_TRUE(method->dex_cache_initialized_static_storage_ != NULL);
+ EXPECT_EQ(method->declaring_class_->dex_cache_->GetStrings(),
+ method->dex_cache_strings_);
+ EXPECT_EQ(method->declaring_class_->dex_cache_->GetResolvedTypes(),
+ method->dex_cache_resolved_types_);
+ EXPECT_EQ(method->declaring_class_->dex_cache_->GetResolvedMethods(),
+ method->dex_cache_resolved_methods_);
+ EXPECT_EQ(method->declaring_class_->dex_cache_->GetResolvedFields(),
+ method->dex_cache_resolved_fields_);
EXPECT_EQ(method->declaring_class_->dex_cache_->GetCodeAndDirectMethods(),
method->dex_cache_code_and_direct_methods_);
+ EXPECT_EQ(method->declaring_class_->dex_cache_->GetInitializedStaticStorage(),
+ method->dex_cache_initialized_static_storage_);
}
void AssertField(Class* klass, Field* field) {
diff --git a/src/compiler.cc b/src/compiler.cc
index c8ff794..7644444 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -40,17 +40,17 @@
}
// Class derived values are more complicated, they require the linker and loader
- for (size_t i = 0; i < dex_cache->NumTypes(); i++) {
+ for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) {
class_linker->ResolveType(dex_file, i, dex_cache, class_loader);
}
- for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
+ for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
// unknown if direct or virtual, try both
Method* method = class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, false);
if (method == NULL) {
class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, true);
}
}
- for (size_t i = 0; i < dex_cache->NumFields(); i++) {
+ for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
// unknown if instance or static, try both
Field* field = class_linker->ResolveField(dex_file, i, dex_cache, class_loader, false);
if (field == NULL) {
@@ -117,7 +117,7 @@
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
DexCache* dex_cache = class_linker->FindDexCache(dex_file);
CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
- for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
+ for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
Method* method = dex_cache->GetResolvedMethod(i);
if (method == NULL) {
code_and_direct_methods->SetResolvedDirectMethodTrampoline(i);
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index c83a2a4..bd50742 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -346,7 +346,7 @@
break;
case 3: // Method->DeclaringClass()->GetDexCache()->methodsObjectArr
loadBaseDisp(cUnit, mir, r0,
- art::DexCache::MethodsOffset().Int32Value(), r0,
+ art::DexCache::ResolvedMethodsOffset().Int32Value(), r0,
kWord, INVALID_SREG);
break;
case 4: // Skip past the object header
@@ -444,7 +444,7 @@
break;
case 3: // ...()->GetDexCache()->methodsObjectArr [uses/sets r0]
loadBaseDisp(cUnit, mir, r0,
- art::DexCache::MethodsOffset().Int32Value(), r0,
+ art::DexCache::ResolvedMethodsOffset().Int32Value(), r0,
kWord, INVALID_SREG);
// Load "this" [set r1]
rlArg = oatGetSrc(cUnit, mir, 0);
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 8ab45b5..1e9f203 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -79,18 +79,18 @@
String* string = dex_cache->GetResolvedString(i);
EXPECT_TRUE(string != NULL);
}
- EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumTypes());
- for (size_t i = 0; i < dex_cache->NumTypes(); i++) {
+ EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumResolvedTypes());
+ for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) {
Class* type = dex_cache->GetResolvedType(i);
EXPECT_TRUE(type != NULL);
}
- EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumMethods());
- for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
+ EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumResolvedMethods());
+ for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
Method* method = dex_cache->GetResolvedMethod(i);
EXPECT_TRUE(method != NULL);
}
- EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumFields());
- for (size_t i = 0; i < dex_cache->NumFields(); i++) {
+ EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields());
+ for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
Field* field = dex_cache->GetResolvedField(i);
EXPECT_TRUE(field != NULL);
}
diff --git a/src/dex_cache.cc b/src/dex_cache.cc
index a4538c9..d24c436 100644
--- a/src/dex_cache.cc
+++ b/src/dex_cache.cc
@@ -11,22 +11,25 @@
void DexCache::Init(String* location,
ObjectArray<String>* strings,
- ObjectArray<Class>* types,
- ObjectArray<Method>* methods,
- ObjectArray<Field>* fields,
- CodeAndDirectMethods* code_and_direct_methods) {
+ ObjectArray<Class>* resolved_types,
+ ObjectArray<Method>* resolved_methods,
+ ObjectArray<Field>* resolved_fields,
+ CodeAndDirectMethods* code_and_direct_methods,
+ ObjectArray<StaticStorageBase>* initialized_static_storage) {
CHECK(location != NULL);
CHECK(strings != NULL);
- CHECK(types != NULL);
- CHECK(methods != NULL);
- CHECK(fields != NULL);
+ CHECK(resolved_types != NULL);
+ CHECK(resolved_methods != NULL);
+ CHECK(resolved_fields != NULL);
CHECK(code_and_direct_methods != NULL);
- Set(kLocation, location);
- Set(kStrings, strings);
- Set(kTypes, types);
- Set(kMethods, methods);
- Set(kFields, fields);
- Set(kCodeAndDirectMethods, code_and_direct_methods);
+ CHECK(initialized_static_storage != NULL);
+ Set(kLocation, location);
+ Set(kStrings, strings);
+ Set(kResolvedTypes, resolved_types);
+ Set(kResolvedMethods, resolved_methods);
+ Set(kResolvedFields, resolved_fields);
+ Set(kCodeAndDirectMethods, code_and_direct_methods);
+ Set(kInitializedStaticStorage, initialized_static_storage);
}
} // namespace art
diff --git a/src/dex_cache.h b/src/dex_cache.h
index 1e46a90..0d217bc 100644
--- a/src/dex_cache.h
+++ b/src/dex_cache.h
@@ -43,6 +43,10 @@
return kMax * elements;
}
+ size_t NumCodeAndDirectMethods() const {
+ return GetLength() / kMax;
+ }
+
private:
enum TupleIndex {
kCode = 0,
@@ -59,7 +63,8 @@
ObjectArray<Class>* types,
ObjectArray<Method>* methods,
ObjectArray<Field>* fields,
- CodeAndDirectMethods* code_and_direct_methods);
+ CodeAndDirectMethods* code_and_direct_methods,
+ ObjectArray<StaticStorageBase>* initialized_static_storage);
String* GetLocation() const {
return Get(kLocation)->AsString();
@@ -70,34 +75,38 @@
kStrings * sizeof(Object*));
}
- static MemberOffset FieldsOffset() {
+ static MemberOffset ResolvedFieldsOffset() {
return MemberOffset(DataOffset().Int32Value() +
- kFields * sizeof(Object*));
+ kResolvedFields * sizeof(Object*));
}
- static MemberOffset MethodsOffset() {
+ static MemberOffset ResolvedMethodsOffset() {
return MemberOffset(DataOffset().Int32Value() +
- kMethods * sizeof(Object*));
+ kResolvedMethods * sizeof(Object*));
}
size_t NumStrings() const {
return GetStrings()->GetLength();
}
- size_t NumTypes() const {
- return GetTypes()->GetLength();
+ size_t NumResolvedTypes() const {
+ return GetResolvedTypes()->GetLength();
}
- size_t NumMethods() const {
- return GetMethods()->GetLength();
+ size_t NumResolvedMethods() const {
+ return GetResolvedMethods()->GetLength();
}
- size_t NumFields() const {
- return GetFields()->GetLength();
+ size_t NumResolvedFields() const {
+ return GetResolvedFields()->GetLength();
}
size_t NumCodeAndDirectMethods() const {
- return GetCodeAndDirectMethods()->GetLength();
+ return GetCodeAndDirectMethods()->NumCodeAndDirectMethods();
+ }
+
+ size_t NumInitializedStaticStorage() const {
+ return GetInitializedStaticStorage()->GetLength();
}
String* GetResolvedString(uint32_t string_idx) const {
@@ -109,44 +118,47 @@
}
Class* GetResolvedType(uint32_t type_idx) const {
- return GetTypes()->Get(type_idx);
+ return GetResolvedTypes()->Get(type_idx);
}
void SetResolvedType(uint32_t type_idx, Class* resolved) {
- GetTypes()->Set(type_idx, resolved);
+ GetResolvedTypes()->Set(type_idx, resolved);
}
Method* GetResolvedMethod(uint32_t method_idx) const {
- return GetMethods()->Get(method_idx);
+ return GetResolvedMethods()->Get(method_idx);
}
void SetResolvedMethod(uint32_t method_idx, Method* resolved) {
- GetMethods()->Set(method_idx, resolved);
+ GetResolvedMethods()->Set(method_idx, resolved);
}
Field* GetResolvedField(uint32_t field_idx) const {
- return GetFields()->Get(field_idx);
+ return GetResolvedFields()->Get(field_idx);
}
void SetResolvedfield(uint32_t field_idx, Field* resolved) {
- GetFields()->Set(field_idx, resolved);
+ GetResolvedFields()->Set(field_idx, resolved);
}
ObjectArray<String>* GetStrings() const {
return static_cast<ObjectArray<String>*>(GetNonNull(kStrings));
}
- ObjectArray<Class>* GetTypes() const {
- return static_cast<ObjectArray<Class>*>(GetNonNull(kTypes));
+ ObjectArray<Class>* GetResolvedTypes() const {
+ return static_cast<ObjectArray<Class>*>(GetNonNull(kResolvedTypes));
}
- ObjectArray<Method>* GetMethods() const {
- return static_cast<ObjectArray<Method>*>(GetNonNull(kMethods));
+ ObjectArray<Method>* GetResolvedMethods() const {
+ return static_cast<ObjectArray<Method>*>(GetNonNull(kResolvedMethods));
}
- ObjectArray<Field>* GetFields() const {
- return static_cast<ObjectArray<Field>*>(GetNonNull(kFields));
+ ObjectArray<Field>* GetResolvedFields() const {
+ return static_cast<ObjectArray<Field>*>(GetNonNull(kResolvedFields));
}
CodeAndDirectMethods* GetCodeAndDirectMethods() const {
return static_cast<CodeAndDirectMethods*>(GetNonNull(kCodeAndDirectMethods));
}
+ ObjectArray<StaticStorageBase>* GetInitializedStaticStorage() const {
+ return static_cast<ObjectArray<StaticStorageBase>*>(GetNonNull(kInitializedStaticStorage));
+ }
static size_t LengthAsArray() {
return kMax;
@@ -155,13 +167,14 @@
private:
enum ArrayIndex {
- kLocation = 0,
- kStrings = 1,
- kTypes = 2,
- kMethods = 3,
- kFields = 4,
- kCodeAndDirectMethods = 5,
- kMax = 6,
+ kLocation = 0,
+ kStrings = 1,
+ kResolvedTypes = 2,
+ kResolvedMethods = 3,
+ kResolvedFields = 4,
+ kCodeAndDirectMethods = 5,
+ kInitializedStaticStorage = 6,
+ kMax = 7,
};
Object* GetNonNull(ArrayIndex array_index) const {
diff --git a/src/dex_cache_test.cc b/src/dex_cache_test.cc
index 6ecaa18..4c0939a 100644
--- a/src/dex_cache_test.cc
+++ b/src/dex_cache_test.cc
@@ -20,23 +20,31 @@
ASSERT_TRUE(dex_cache != NULL);
EXPECT_EQ(java_lang_dex_file_->NumStringIds(), dex_cache->NumStrings());
- EXPECT_EQ(java_lang_dex_file_->NumTypeIds(), dex_cache->NumTypes());
- EXPECT_EQ(java_lang_dex_file_->NumMethodIds(), dex_cache->NumMethods());
- EXPECT_EQ(java_lang_dex_file_->NumFieldIds(), dex_cache->NumFields());
+ 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_->NumMethodIds(), dex_cache->NumCodeAndDirectMethods());
+ EXPECT_EQ(java_lang_dex_file_->NumTypeIds(), dex_cache->NumInitializedStaticStorage());
EXPECT_LE(0, dex_cache->GetStrings()->GetLength());
- EXPECT_LE(0, dex_cache->GetTypes()->GetLength());
- EXPECT_LE(0, dex_cache->GetMethods()->GetLength());
- EXPECT_LE(0, dex_cache->GetFields()->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->GetCodeAndDirectMethods()->GetLength());
+ EXPECT_LE(0, dex_cache->GetInitializedStaticStorage()->GetLength());
EXPECT_EQ(java_lang_dex_file_->NumStringIds(),
static_cast<uint32_t>(dex_cache->GetStrings()->GetLength()));
EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),
- static_cast<uint32_t>(dex_cache->GetTypes()->GetLength()));
+ static_cast<uint32_t>(dex_cache->GetResolvedTypes()->GetLength()));
EXPECT_EQ(java_lang_dex_file_->NumMethodIds(),
- static_cast<uint32_t>(dex_cache->GetMethods()->GetLength()));
+ static_cast<uint32_t>(dex_cache->GetResolvedMethods()->GetLength()));
EXPECT_EQ(java_lang_dex_file_->NumFieldIds(),
- static_cast<uint32_t>(dex_cache->GetFields()->GetLength()));
+ static_cast<uint32_t>(dex_cache->GetResolvedFields()->GetLength()));
+ EXPECT_EQ(java_lang_dex_file_->NumMethodIds(),
+ static_cast<uint32_t>(dex_cache->GetCodeAndDirectMethods()->NumCodeAndDirectMethods()));
+ EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),
+ static_cast<uint32_t>(dex_cache->GetInitializedStaticStorage()->GetLength()));
}
} // namespace art
diff --git a/src/object.cc b/src/object.cc
index 7328dbe..f938bc2 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -31,7 +31,8 @@
}
Array* Array::AllocFromCode(uint32_t type_idx, Method* method, int32_t component_count) {
- Class* klass = method->dex_cache_types_->Get(type_idx);
+ // TODO: throw on negative component_count
+ Class* klass = method->dex_cache_resolved_types_->Get(type_idx);
if (klass == NULL) {
klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
if (klass == NULL || !klass->IsArrayClass()) {
@@ -43,7 +44,7 @@
}
Object* Class::NewInstanceFromCode(uint32_t type_idx, Method* method) {
- Class* klass = method->dex_cache_types_->Get(type_idx);
+ Class* klass = method->dex_cache_resolved_types_->Get(type_idx);
if (klass == NULL) {
klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
if (klass == NULL) {
diff --git a/src/object.h b/src/object.h
index 51bf999..d299c5b 100644
--- a/src/object.h
+++ b/src/object.h
@@ -25,6 +25,7 @@
class Monitor;
class Method;
class Object;
+class StaticStorageBase;
class String;
template<class T> class ObjectArray;
template<class T> class PrimitiveArray;
@@ -720,10 +721,11 @@
// short cuts to declaring_class_->dex_cache_ members for fast compiled code
// access
ObjectArray<String>* dex_cache_strings_;
- ObjectArray<Class>* dex_cache_types_;
- ObjectArray<Method>* dex_cache_methods_;
- ObjectArray<Field>* dex_cache_fields_;
+ ObjectArray<Class>* dex_cache_resolved_types_;
+ ObjectArray<Method>* dex_cache_resolved_methods_;
+ ObjectArray<Field>* dex_cache_resolved_fields_;
CodeAndDirectMethods* dex_cache_code_and_direct_methods_;
+ ObjectArray<StaticStorageBase>* dex_cache_initialized_static_storage_;
bool is_direct_;
@@ -899,8 +901,14 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(PathClassLoader);
};
+// Type for the InitializedStaticStorage table. Currently the Class
+// provides the static storage. However, this might change to improve
+// image sharing, so we use this type to avoid assumptions on the
+// current storage.
+class StaticStorageBase {};
+
// Class objects.
-class Class : public Object {
+class Class : public Object, public StaticStorageBase {
public:
// Class Status