More field order validation.
This is to set me up to remove the redundant fields like declaring
class and name from field and method.
Change-Id: Ie834c615b33caed89c443fa23c25b7757d4b7ef3
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 7c33930..cdcf8fb 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -398,18 +398,44 @@
AssertDexFile(libcore_dex_file.get());
}
-// C++ fields must exactly match the fields in the Java class. If this fails,
+// C++ fields must exactly match the fields in the Java classes. If this fails,
// reorder the fields in the C++ class. Managed class fields are ordered by
// ClassLinker::LinkInstanceFields.
-TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaLangString) {
- scoped_ptr<DexFile> libcore_dex_file(GetLibCoreDex());
- EXPECT_TRUE(libcore_dex_file.get() != NULL); // Passes on host only until we have DexFile::OpenJar
- class_linker_->RegisterDexFile(libcore_dex_file.get());
- Class* string = class_linker_->FindClass( "Ljava/lang/String;", NULL, libcore_dex_file.get());
+TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaCppUnionClasses) {
+ UseLibCoreDex();
+ Class* string = class_linker_->FindClass( "Ljava/lang/String;", NULL, java_lang_dex_file_.get());
+ ASSERT_EQ(4U, string->NumInstanceFields());
EXPECT_EQ("value", string->GetInstanceField(0)->GetName());
EXPECT_EQ("hashCode", string->GetInstanceField(1)->GetName());
EXPECT_EQ("offset", string->GetInstanceField(2)->GetName());
EXPECT_EQ("count", string->GetInstanceField(3)->GetName());
+
+ Class* accessible_object = class_linker_->FindClass("Ljava/lang/reflect/AccessibleObject;", NULL, java_lang_dex_file_.get());
+ ASSERT_EQ(1U, accessible_object->NumInstanceFields());
+ EXPECT_EQ("flag", accessible_object->GetInstanceField(0)->GetName());
+
+ Class* field = class_linker_->FindClass("Ljava/lang/reflect/Field;", NULL, java_lang_dex_file_.get());
+ ASSERT_EQ(6U, field->NumInstanceFields());
+ EXPECT_EQ("declaringClass", field->GetInstanceField(0)->GetName());
+ EXPECT_EQ("genericType", field->GetInstanceField(1)->GetName());
+ EXPECT_EQ("type", field->GetInstanceField(2)->GetName());
+ EXPECT_EQ("name", field->GetInstanceField(3)->GetName());
+ EXPECT_EQ("slot", field->GetInstanceField(4)->GetName());
+ EXPECT_EQ("genericTypesAreInitialized", field->GetInstanceField(5)->GetName());
+
+ Class* method = class_linker_->FindClass("Ljava/lang/reflect/Method;", NULL, java_lang_dex_file_.get());
+ ASSERT_EQ(11U, method->NumInstanceFields());
+ EXPECT_EQ("declaringClass", method->GetInstanceField( 0)->GetName());
+ EXPECT_EQ("exceptionTypes", method->GetInstanceField( 1)->GetName());
+ EXPECT_EQ("formalTypeParameters", method->GetInstanceField( 2)->GetName());
+ EXPECT_EQ("genericExceptionTypes", method->GetInstanceField( 3)->GetName());
+ EXPECT_EQ("genericParameterTypes", method->GetInstanceField( 4)->GetName());
+ EXPECT_EQ("genericReturnType", method->GetInstanceField( 5)->GetName());
+ EXPECT_EQ("returnType", method->GetInstanceField( 6)->GetName());
+ EXPECT_EQ("name", method->GetInstanceField( 7)->GetName());
+ EXPECT_EQ("parameterTypes", method->GetInstanceField( 8)->GetName());
+ EXPECT_EQ("genericTypesAreInitialized", method->GetInstanceField( 9)->GetName());
+ EXPECT_EQ("slot", method->GetInstanceField(10)->GetName());
}
} // namespace art
diff --git a/src/common_test.h b/src/common_test.h
index c4a3d1f..cfc0a5f 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -211,6 +211,18 @@
return DexFile::OpenFile(libcore_dex_file_name.c_str());
}
+ void UseLibCoreDex() {
+ delete runtime_.release();
+ java_lang_dex_file_.reset(GetLibCoreDex());
+
+ std::vector<DexFile*> boot_class_path;
+ boot_class_path.push_back(java_lang_dex_file_.get());
+
+ runtime_.reset(Runtime::Create(boot_class_path));
+ ASSERT_TRUE(runtime_ != NULL);
+ class_linker_ = runtime_->GetClassLinker();
+ }
+
bool is_host_;
scoped_ptr<DexFile> java_lang_dex_file_;
scoped_ptr<Runtime> runtime_;
diff --git a/src/object.h b/src/object.h
index fbeac8f..4d68d30 100644
--- a/src/object.h
+++ b/src/object.h
@@ -23,6 +23,7 @@
class Monitor;
class Method;
class Object;
+class String;
template<class T> class ObjectArray;
class StaticField;
@@ -244,7 +245,13 @@
DISALLOW_COPY_AND_ASSIGN(ObjectLock);
};
-class Field : public Object {
+class AccessibleObject : public Object {
+ private:
+ // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+ uint32_t java_flag_;
+};
+
+class Field : public AccessibleObject {
public:
Class* GetDeclaringClass() const {
return declaring_class_;
@@ -263,16 +270,13 @@
}
public: // TODO: private
-#define FIELD_FIELD_SLOTS 1+6
- // AccessibleObject #0 flag
- // Field #0 declaringClass
- // Field #1 genericType
- // Field #2 genericTypesAreInitialized
- // Field #3 name
- // Field #4 slot
- // Field #5 type
- uint32_t instance_data_[FIELD_FIELD_SLOTS];
-#undef FIELD_FIELD_SLOTS
+ // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+ Class* java_declaring_class_;
+ Object* java_generic_type_;
+ uint32_t java_generic_types_are_initialized_;
+ String* java_name_;
+ uint32_t java_slot_;
+ Class* java_type_;
// The class in which this field is declared.
Class* declaring_class_;
@@ -371,7 +375,7 @@
StaticField();
};
-class Method : public Object {
+class Method : public AccessibleObject {
public:
// Returns the method name, e.g. "<init>" or "eatLunch"
const StringPiece& GetName() const {
@@ -435,21 +439,18 @@
uint32_t NumArgRegisters();
public: // TODO: private
-#define METHOD_FIELD_SLOTS 1+11
- // AccessibleObject #0 flag
- // Method #0 declaringClass
- // Method #1 exceptionTypes
- // Method #2 formalTypeParameters
- // Method #3 genericExceptionTypes
- // Method #4 genericParameterTypes
- // Method #5 genericReturnType
- // Method #6 genericTypesAreInitialized
- // Method #7 name
- // Method #8 parameterTypes
- // Method #9 returnType
- // Method #10 slot
- uint32_t instance_data_[METHOD_FIELD_SLOTS];
-#undef METHOD_FIELD_SLOTS
+ // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+ Class* java_declaring_class_;
+ ObjectArray<Class>* java_exception_types_;
+ Object* java_formal_type_parameters_;
+ Object* java_generic_exception_types_;
+ Object* java_generic_parameter_types_;
+ Object* java_generic_return_type_;
+ Class* java_return_type_;
+ String* java_name_;
+ ObjectArray<Class>* java_parameter_types_;
+ uint32_t java_generic_types_are_initialized_;
+ uint32_t java_slot_;
bool IsReturnAReference() const {
return (shorty_[0] == 'L') || (shorty_[0] == '[');
@@ -1053,7 +1054,7 @@
}
public: // TODO: private
- // Field order required by test "ValidateFieldOrderOfJavaLangString".
+ // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
CharArray* array_;
uint32_t hash_code_;