Store static field values in arrays.
Each static field is stored in one of three arrays:
- references are stored in static_references_
- 64 bit primitives are stored in static_64bit_primitives_
- everything else is in static_32bit_primitives_
Change-Id: I1c0e182582f776c62edbd9bd97ffd4fd7e516c99
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 925a3b3..3f9f7ab 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -58,6 +58,12 @@
Class* char_array_class = AllocClass(java_lang_Class);
CHECK(char_array_class != NULL);
+ // int[] and long[] are used for static field storage
+ Class* int_array_class = AllocClass(java_lang_Class);
+ CHECK(int_array_class != NULL);
+ Class* long_array_class = AllocClass(java_lang_Class);
+ CHECK(long_array_class != NULL);
+
// Field and Method are necessary so that FindClass can link members
Class* java_lang_reflect_Field = AllocClass(java_lang_Class);
CHECK(java_lang_reflect_Field != NULL);
@@ -77,6 +83,8 @@
class_roots_->Set(kObjectArrayClass, object_array_class);
class_roots_->Set(kJavaLangString, java_lang_String);
class_roots_->Set(kCharArrayClass, char_array_class);
+ class_roots_->Set(kIntArrayClass, int_array_class);
+ class_roots_->Set(kLongArrayClass, long_array_class);
class_roots_->Set(kJavaLangReflectField, java_lang_reflect_Field);
class_roots_->Set(kJavaLangReflectMethod, java_lang_reflect_Method);
// now that these are registered, we can use AllocClass() and AllocObjectArray
@@ -169,9 +177,13 @@
class_roots_->Set(kPrimitiveVoid, CreatePrimitiveClass("V"));
// now we can use FindSystemClass for anything, including for "[C"
- // run char[] through FindClass to complete initialization
+ // run char[], int[] and long[] through FindClass to complete initialization
Class* found_char_array_class = FindSystemClass("[C");
CHECK_EQ(char_array_class, found_char_array_class);
+ Class* found_int_array_class = FindSystemClass("[I");
+ CHECK_EQ(int_array_class, found_int_array_class);
+ Class* found_long_array_class = FindSystemClass("[J");
+ CHECK_EQ(long_array_class, found_long_array_class);
// ensure all class_roots_ were initialized
for (size_t i = 0; i < kClassRootsMax; i++) {
@@ -460,7 +472,8 @@
Class* klass,
Field* dst) {
const DexFile::FieldId& field_id = dex_file.GetFieldId(src.field_idx_);
- dst->klass_ = klass;
+ dst->java_declaring_class_ = klass;
+ dst->declaring_class_ = klass;
dst->name_ = ResolveString(klass, field_id.name_idx_, dex_file);
dst->descriptor_.set(dex_file.dexStringByTypeIdx(field_id.type_idx_));
dst->access_flags_ = src.access_flags_;
@@ -471,7 +484,8 @@
Class* klass,
Method* dst) {
const DexFile::MethodId& method_id = dex_file.GetMethodId(src.method_idx_);
- dst->klass_ = klass;
+ dst->java_declaring_class_ = klass;
+ dst->declaring_class_ = klass;
dst->name_ = ResolveString(klass, method_id.name_idx_, dex_file);
{
int32_t utf16_length;
@@ -640,6 +654,10 @@
new_class = GetClassRoot(kObjectArrayClass);
} else if (descriptor == "[C") {
new_class = GetClassRoot(kCharArrayClass);
+ } else if (descriptor == "[I") {
+ new_class = GetClassRoot(kIntArrayClass);
+ } else if (descriptor == "[J") {
+ new_class = GetClassRoot(kLongArrayClass);
}
}
if (new_class == NULL) {
@@ -1046,6 +1064,9 @@
if (!LinkMethods(klass)) {
return false;
}
+ if (!LinkStaticFields(klass)) {
+ return false;
+ }
if (!LinkInstanceFields(klass)) {
return false;
}
@@ -1329,6 +1350,42 @@
}
}
+// Each static field will be stored in one of three arrays: static_references_,
+// static_32bit_primitives_, or static_64bit_primitives_. This assigns each
+// field a slot in its array and create the arrays.
+bool ClassLinker::LinkStaticFields(Class* klass) {
+ size_t next_reference_slot = 0;
+ size_t next_32bit_primitive_slot = 0;
+ size_t next_64bit_primitive_slot = 0;
+
+ for (size_t i = 0; i < klass->NumStaticFields(); i++) {
+ StaticField* field = klass->GetStaticField(i);
+ char type = field->GetType();
+ if (type == '[' || type == 'L') {
+ field->java_slot_ = next_reference_slot++;
+ } else if (type == 'J' || type == 'D') {
+ field->java_slot_ = next_64bit_primitive_slot++;
+ } else {
+ field->java_slot_ = next_32bit_primitive_slot++;
+ }
+ }
+
+ if (next_reference_slot > 0) {
+ Class* array_class = GetClassRoot(kObjectArrayClass);
+ klass->static_references_ = ObjectArray<Object>::Alloc(array_class, next_reference_slot);
+ }
+ if (next_32bit_primitive_slot > 0) {
+ Class* array_class = GetClassRoot(kIntArrayClass);
+ klass->static_32bit_primitives_ = IntArray::Alloc(array_class, next_32bit_primitive_slot);
+ }
+ if (next_64bit_primitive_slot > 0) {
+ Class* array_class = GetClassRoot(kLongArrayClass);
+ klass->static_64bit_primitives_ = LongArray::Alloc(array_class, next_64bit_primitive_slot);
+ }
+
+ return true;
+}
+
bool ClassLinker::LinkInstanceFields(Class* klass) {
int field_offset;
if (klass->GetSuperClass() != NULL) {