Change dex cache to be java object instead of array, add pointer to dex file in dex cache.
Generic clean up to facilitate having GDB macros for Pretty* helper functions.
Improved cleanliness of DexCache since having it as an object array was not the best solution.
Fixed a bug in InOrderWalk caused by ResolveType sometimes allocating classes.
Rename C++ Method to AbstractMethod and add two new classes Constructor, Method which both inherit from AbstractMethod.
Rename done to have the C++ code be closer to the java code.
Change-Id: I4995b4c5e47a3822192b08afa24a639d3b1f4da9
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index a0b4f1c..106598e 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -135,7 +135,7 @@
EXPECT_STREQ(kh.GetDescriptor(), "Ljava/io/Serializable;");
}
- void AssertMethod(Method* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ void AssertMethod(AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
MethodHelper mh(method);
EXPECT_TRUE(method != NULL);
EXPECT_TRUE(method->GetClass() != NULL);
@@ -232,14 +232,14 @@
EXPECT_TRUE(klass->CanAccess(klass));
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
- Method* method = klass->GetDirectMethod(i);
+ AbstractMethod* method = klass->GetDirectMethod(i);
AssertMethod(method);
EXPECT_TRUE(method->IsDirect());
EXPECT_EQ(klass, method->GetDeclaringClass());
}
for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
- Method* method = klass->GetVirtualMethod(i);
+ AbstractMethod* method = klass->GetVirtualMethod(i);
AssertMethod(method);
EXPECT_FALSE(method->IsDirect());
EXPECT_TRUE(method->GetDeclaringClass()->IsAssignableFrom(klass));
@@ -325,7 +325,7 @@
class_linker_->VisitRoots(TestRootVisitor, NULL);
// Verify the dex cache has resolution methods in all resolved method slots
DexCache* dex_cache = class_linker_->FindDexCache(*dex);
- ObjectArray<Method>* resolved_methods = dex_cache->GetResolvedMethods();
+ ObjectArray<AbstractMethod>* resolved_methods = dex_cache->GetResolvedMethods();
for (size_t i = 0; i < static_cast<size_t>(resolved_methods->GetLength()); i++) {
EXPECT_TRUE(resolved_methods->Get(i) != NULL);
}
@@ -452,36 +452,41 @@
};
};
-struct MethodOffsets : public CheckOffsets<Method> {
- MethodOffsets() : CheckOffsets<Method>(false, "Ljava/lang/reflect/Method;") {
+struct AbstractMethodOffsets : public CheckOffsets<AbstractMethod> {
+ AbstractMethodOffsets() : CheckOffsets<AbstractMethod>(false, "Ljava/lang/reflect/AbstractMethod;") {
// alphabetical references
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, declaring_class_), "declaringClass"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_initialized_static_storage_), "dexCacheInitializedStaticStorage"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_methods_), "dexCacheResolvedMethods"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_types_), "dexCacheResolvedTypes"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_strings_), "dexCacheStrings"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, declaring_class_), "declaringClass"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, dex_cache_initialized_static_storage_), "dexCacheInitializedStaticStorage"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, dex_cache_resolved_methods_), "dexCacheResolvedMethods"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, dex_cache_resolved_types_), "dexCacheResolvedTypes"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, dex_cache_strings_), "dexCacheStrings"));
// alphabetical 32-bit
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, access_flags_), "accessFlags"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, code_), "code"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, code_item_offset_), "codeItemOffset"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, core_spill_mask_), "coreSpillMask"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, fp_spill_mask_), "fpSpillMask"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, frame_size_in_bytes_), "frameSizeInBytes"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, native_gc_map_), "gcMap"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, invoke_stub_), "invokeStub"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, mapping_table_), "mappingTable"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, method_dex_index_), "methodDexIndex"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, method_index_), "methodIndex"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, native_method_), "nativeMethod"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, vmap_table_), "vmapTable"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, access_flags_), "accessFlags"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, code_), "code"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, code_item_offset_), "codeItemOffset"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, core_spill_mask_), "coreSpillMask"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, fp_spill_mask_), "fpSpillMask"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, frame_size_in_bytes_), "frameSizeInBytes"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, native_gc_map_), "gcMap"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, invoke_stub_), "invokeStub"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, mapping_table_), "mappingTable"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, method_dex_index_), "methodDexIndex"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, method_index_), "methodIndex"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, native_method_), "nativeMethod"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, vmap_table_), "vmapTable"));
};
};
-struct ConstructorOffsets : public MethodOffsets {
- ConstructorOffsets() : MethodOffsets() {
- // We use Method* for both java.lang.reflect.Constructor and java.lang.reflect.Method.
- class_descriptor = "Ljava/lang/reflect/Constructor;";
+struct ConstructorOffsets : public CheckOffsets<Constructor> {
+ // java.lang.reflect.Constructor is a subclass of java.lang.reflect.AbstractMethod
+ ConstructorOffsets() : CheckOffsets<Constructor>(false, "Ljava/lang/reflect/Constructor;") {
+ }
+};
+
+struct MethodOffsets : public CheckOffsets<Method> {
+ // java.lang.reflect.Method is a subclass of java.lang.reflect.AbstractMethod
+ MethodOffsets() : CheckOffsets<Method>(false, "Ljava/lang/reflect/Method;") {
}
};
@@ -604,6 +609,19 @@
};
};
+struct DexCacheOffsets : public CheckOffsets<DexCache> {
+ DexCacheOffsets() : CheckOffsets<DexCache>(false, "Ljava/lang/DexCache;") {
+ // alphabetical references
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(DexCache, initialized_static_storage_), "initializedStaticStorage"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(DexCache, location_), "location"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(DexCache, resolved_fields_), "resolvedFields"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(DexCache, resolved_methods_), "resolvedMethods"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(DexCache, resolved_types_), "resolvedTypes"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(DexCache, strings_), "strings"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(DexCache, dex_file_), "dexFile"));
+ };
+};
+
// 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::LinkFields.
@@ -611,14 +629,16 @@
ScopedObjectAccess soa(Thread::Current());
EXPECT_TRUE(ObjectOffsets().Check());
EXPECT_TRUE(ConstructorOffsets().Check());
- EXPECT_TRUE(FieldOffsets().Check());
EXPECT_TRUE(MethodOffsets().Check());
+ EXPECT_TRUE(FieldOffsets().Check());
+ EXPECT_TRUE(AbstractMethodOffsets().Check());
EXPECT_TRUE(ClassOffsets().Check());
EXPECT_TRUE(StringOffsets().Check());
EXPECT_TRUE(ThrowableOffsets().Check());
EXPECT_TRUE(StackTraceElementOffsets().Check());
EXPECT_TRUE(ClassLoaderOffsets().Check());
EXPECT_TRUE(ProxyOffsets().Check());
+ EXPECT_TRUE(DexCacheOffsets().Check());
EXPECT_TRUE(ClassClassOffsets().Check());
EXPECT_TRUE(StringClassOffsets().Check());
@@ -844,7 +864,7 @@
// Static final primitives that are initialized by a compile-time constant
// expression resolve to a copy of a constant value from the constant pool.
// So <clinit> should be null.
- Method* clinit = statics->FindDirectMethod("<clinit>", "()V");
+ AbstractMethod* clinit = statics->FindDirectMethod("<clinit>", "()V");
EXPECT_TRUE(clinit == NULL);
EXPECT_EQ(9U, statics->NumStaticFields());
@@ -931,15 +951,15 @@
EXPECT_TRUE(K->IsAssignableFrom(B));
EXPECT_TRUE(J->IsAssignableFrom(B));
- Method* Ii = I->FindVirtualMethod("i", "()V");
- Method* Jj1 = J->FindVirtualMethod("j1", "()V");
- Method* Jj2 = J->FindVirtualMethod("j2", "()V");
- Method* Kj1 = K->FindInterfaceMethod("j1", "()V");
- Method* Kj2 = K->FindInterfaceMethod("j2", "()V");
- Method* Kk = K->FindInterfaceMethod("k", "()V");
- Method* Ai = A->FindVirtualMethod("i", "()V");
- Method* Aj1 = A->FindVirtualMethod("j1", "()V");
- Method* Aj2 = A->FindVirtualMethod("j2", "()V");
+ AbstractMethod* Ii = I->FindVirtualMethod("i", "()V");
+ AbstractMethod* Jj1 = J->FindVirtualMethod("j1", "()V");
+ AbstractMethod* Jj2 = J->FindVirtualMethod("j2", "()V");
+ AbstractMethod* Kj1 = K->FindInterfaceMethod("j1", "()V");
+ AbstractMethod* Kj2 = K->FindInterfaceMethod("j2", "()V");
+ AbstractMethod* Kk = K->FindInterfaceMethod("k", "()V");
+ AbstractMethod* Ai = A->FindVirtualMethod("i", "()V");
+ AbstractMethod* Aj1 = A->FindVirtualMethod("j1", "()V");
+ AbstractMethod* Aj2 = A->FindVirtualMethod("j2", "()V");
ASSERT_TRUE(Ii != NULL);
ASSERT_TRUE(Jj1 != NULL);
ASSERT_TRUE(Jj2 != NULL);
@@ -984,8 +1004,8 @@
CHECK(dex_file != NULL);
Class* klass = class_linker_->FindClass("LStaticsFromCode;", class_loader.get());
- Method* clinit = klass->FindDirectMethod("<clinit>", "()V");
- Method* getS0 = klass->FindDirectMethod("getS0", "()Ljava/lang/Object;");
+ AbstractMethod* clinit = klass->FindDirectMethod("<clinit>", "()V");
+ AbstractMethod* getS0 = klass->FindDirectMethod("getS0", "()Ljava/lang/Object;");
const DexFile::StringId* string_id = dex_file->FindStringId("LStaticsFromCode;");
ASSERT_TRUE(string_id != NULL);
const DexFile::TypeId* type_id = dex_file->FindTypeId(dex_file->GetIndexForStringId(*string_id));