summaryrefslogtreecommitdiff
path: root/src/class_linker_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/class_linker_test.cc')
-rw-r--r--src/class_linker_test.cc80
1 files changed, 44 insertions, 36 deletions
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index a7f9c66c51..1eb5e0d1c4 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -29,7 +29,8 @@ namespace art {
class ClassLinkerTest : public CommonTest {
protected:
- void AssertNonExistentClass(const std::string& descriptor) {
+ void AssertNonExistentClass(const std::string& descriptor)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
EXPECT_TRUE(class_linker_->FindSystemClass(descriptor.c_str()) == NULL);
Thread* self = Thread::Current();
EXPECT_TRUE(self->IsExceptionPending());
@@ -39,11 +40,13 @@ class ClassLinkerTest : public CommonTest {
EXPECT_TRUE(exception->InstanceOf(exception_class));
}
- void AssertPrimitiveClass(const std::string& descriptor) {
+ void AssertPrimitiveClass(const std::string& descriptor)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
AssertPrimitiveClass(descriptor, class_linker_->FindSystemClass(descriptor.c_str()));
}
- void AssertPrimitiveClass(const std::string& descriptor, const Class* primitive) {
+ void AssertPrimitiveClass(const std::string& descriptor, const Class* primitive)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
ClassHelper primitive_ch(primitive);
ASSERT_TRUE(primitive != NULL);
ASSERT_TRUE(primitive->GetClass() != NULL);
@@ -79,7 +82,8 @@ class ClassLinkerTest : public CommonTest {
void AssertArrayClass(const std::string& array_descriptor,
const std::string& component_type,
- ClassLoader* class_loader) {
+ ClassLoader* class_loader)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
Class* array = class_linker_->FindClass(array_descriptor.c_str(), class_loader);
ClassHelper array_component_ch(array->GetComponentType());
EXPECT_STREQ(component_type.c_str(), array_component_ch.GetDescriptor());
@@ -87,7 +91,8 @@ class ClassLinkerTest : public CommonTest {
AssertArrayClass(array_descriptor, array);
}
- void AssertArrayClass(const std::string& array_descriptor, Class* array) {
+ void AssertArrayClass(const std::string& array_descriptor, Class* array)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
ClassHelper kh(array);
ASSERT_TRUE(array != NULL);
ASSERT_TRUE(array->GetClass() != NULL);
@@ -130,7 +135,7 @@ class ClassLinkerTest : public CommonTest {
EXPECT_STREQ(kh.GetDescriptor(), "Ljava/io/Serializable;");
}
- void AssertMethod(Method* method) {
+ void AssertMethod(Method* method) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
MethodHelper mh(method);
EXPECT_TRUE(method != NULL);
EXPECT_TRUE(method->GetClass() != NULL);
@@ -151,7 +156,8 @@ class ClassLinkerTest : public CommonTest {
method->GetDexCacheInitializedStaticStorage());
}
- void AssertField(Class* klass, Field* field) {
+ void AssertField(Class* klass, Field* field)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
FieldHelper fh(field);
EXPECT_TRUE(field != NULL);
EXPECT_TRUE(field->GetClass() != NULL);
@@ -160,7 +166,8 @@ class ClassLinkerTest : public CommonTest {
EXPECT_TRUE(fh.GetType() != NULL);
}
- void AssertClass(const std::string& descriptor, Class* klass) {
+ void AssertClass(const std::string& descriptor, Class* klass)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
ClassHelper kh(klass);
EXPECT_STREQ(descriptor.c_str(), kh.GetDescriptor());
if (descriptor == "Ljava/lang/Object;") {
@@ -283,7 +290,8 @@ class ClassLinkerTest : public CommonTest {
total_num_reference_instance_fields == 0);
}
- void AssertDexFileClass(ClassLoader* class_loader, const std::string& descriptor) {
+ void AssertDexFileClass(ClassLoader* class_loader, const std::string& descriptor)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
ASSERT_TRUE(descriptor != NULL);
Class* klass = class_linker_->FindSystemClass(descriptor.c_str());
ASSERT_TRUE(klass != NULL);
@@ -298,7 +306,8 @@ class ClassLinkerTest : public CommonTest {
}
}
- void AssertDexFile(const DexFile* dex, ClassLoader* class_loader) {
+ void AssertDexFile(const DexFile* dex, ClassLoader* class_loader)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
ASSERT_TRUE(dex != NULL);
// Verify all the classes defined in this file
@@ -341,7 +350,7 @@ struct CheckOffsets {
std::string class_descriptor;
std::vector<CheckOffset> offsets;
- bool Check() {
+ bool Check() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
Class* klass = Runtime::Current()->GetClassLinker()->FindSystemClass(class_descriptor.c_str());
CHECK(klass != NULL) << class_descriptor;
@@ -549,21 +558,6 @@ struct ClassLoaderOffsets : public CheckOffsets<ClassLoader> {
};
};
-struct BaseDexClassLoaderOffsets : public CheckOffsets<BaseDexClassLoader> {
- BaseDexClassLoaderOffsets()
- : CheckOffsets<BaseDexClassLoader>(false, "Ldalvik/system/BaseDexClassLoader;") {
- // alphabetical references
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(BaseDexClassLoader, original_library_path_), "originalLibraryPath"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(BaseDexClassLoader, original_path_), "originalPath"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(BaseDexClassLoader, path_list_), "pathList"));
- };
-};
-
-struct PathClassLoaderOffsets : public CheckOffsets<PathClassLoader> {
- PathClassLoaderOffsets()
- : CheckOffsets<PathClassLoader>(false, "Ldalvik/system/PathClassLoader;") {}
-};
-
struct ProxyOffsets : public CheckOffsets<Proxy> {
ProxyOffsets() : CheckOffsets<Proxy>(false, "Ljava/lang/reflect/Proxy;") {
// alphabetical references
@@ -614,6 +608,7 @@ struct MethodClassOffsets : public CheckOffsets<MethodClass> {
// reorder the fields in the C++ class. Managed class fields are ordered by
// ClassLinker::LinkFields.
TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaCppUnionClasses) {
+ ScopedObjectAccess soa(Thread::Current());
EXPECT_TRUE(ObjectOffsets().Check());
EXPECT_TRUE(ConstructorOffsets().Check());
EXPECT_TRUE(FieldOffsets().Check());
@@ -623,8 +618,6 @@ TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaCppUnionClasses) {
EXPECT_TRUE(ThrowableOffsets().Check());
EXPECT_TRUE(StackTraceElementOffsets().Check());
EXPECT_TRUE(ClassLoaderOffsets().Check());
- EXPECT_TRUE(BaseDexClassLoaderOffsets().Check());
- EXPECT_TRUE(PathClassLoaderOffsets().Check());
EXPECT_TRUE(ProxyOffsets().Check());
EXPECT_TRUE(ClassClassOffsets().Check());
@@ -634,12 +627,14 @@ TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaCppUnionClasses) {
}
TEST_F(ClassLinkerTest, FindClassNonexistent) {
+ ScopedObjectAccess soa(Thread::Current());
AssertNonExistentClass("NoSuchClass;");
AssertNonExistentClass("LNoSuchClass;");
}
TEST_F(ClassLinkerTest, FindClassNested) {
- SirtRef<ClassLoader> class_loader(LoadDex("Nested"));
+ ScopedObjectAccess soa(Thread::Current());
+ SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(LoadDex("Nested")));
Class* outer = class_linker_->FindClass("LNested;", class_loader.get());
ASSERT_TRUE(outer != NULL);
@@ -653,6 +648,7 @@ TEST_F(ClassLinkerTest, FindClassNested) {
}
TEST_F(ClassLinkerTest, FindClass_Primitives) {
+ ScopedObjectAccess soa(Thread::Current());
const std::string expected("BCDFIJSZV");
for (int ch = 1; ch < 256; ++ch) {
std::string descriptor;
@@ -666,6 +662,7 @@ TEST_F(ClassLinkerTest, FindClass_Primitives) {
}
TEST_F(ClassLinkerTest, FindClass) {
+ ScopedObjectAccess soa(Thread::Current());
Class* JavaLangObject = class_linker_->FindSystemClass("Ljava/lang/Object;");
ClassHelper kh(JavaLangObject);
ASSERT_TRUE(JavaLangObject != NULL);
@@ -701,7 +698,7 @@ TEST_F(ClassLinkerTest, FindClass) {
EXPECT_EQ(0U, JavaLangObject->NumStaticFields());
EXPECT_EQ(0U, kh.NumDirectInterfaces());
- SirtRef<ClassLoader> class_loader(LoadDex("MyClass"));
+ SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(LoadDex("MyClass")));
AssertNonExistentClass("LMyClass;");
Class* MyClass = class_linker_->FindClass("LMyClass;", class_loader.get());
kh.ChangeClass(MyClass);
@@ -746,12 +743,14 @@ TEST_F(ClassLinkerTest, FindClass) {
}
TEST_F(ClassLinkerTest, LibCore) {
+ ScopedObjectAccess soa(Thread::Current());
AssertDexFile(java_lang_dex_file_, NULL);
}
// The first reference array element must be a multiple of 4 bytes from the
// start of the object
TEST_F(ClassLinkerTest, ValidateObjectArrayElementsOffset) {
+ ScopedObjectAccess soa(Thread::Current());
Class* array_class = class_linker_->FindSystemClass("[Ljava/lang/String;");
ObjectArray<String>* array = ObjectArray<String>::Alloc(array_class, 0);
uint32_t array_offset = reinterpret_cast<uint32_t>(array);
@@ -765,6 +764,7 @@ TEST_F(ClassLinkerTest, ValidateObjectArrayElementsOffset) {
}
TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) {
+ ScopedObjectAccess soa(Thread::Current());
SirtRef<LongArray> long_array(LongArray::Alloc(0));
EXPECT_EQ(class_linker_->FindSystemClass("[J"), long_array->GetClass());
uintptr_t data_offset = reinterpret_cast<uintptr_t>(long_array->GetData());
@@ -796,6 +796,7 @@ TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) {
TEST_F(ClassLinkerTest, ValidateBoxedTypes) {
// Validate that the "value" field is always the 0th field in each of java.lang's box classes.
// This lets UnboxPrimitive avoid searching for the field by name at runtime.
+ ScopedObjectAccess soa(Thread::Current());
Class* c;
c = class_linker_->FindClass("Ljava/lang/Boolean;", NULL);
FieldHelper fh(c->GetIFields()->Get(0));
@@ -824,8 +825,9 @@ TEST_F(ClassLinkerTest, ValidateBoxedTypes) {
}
TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) {
- SirtRef<ClassLoader> class_loader_1(LoadDex("MyClass"));
- SirtRef<ClassLoader> class_loader_2(LoadDex("MyClass"));
+ ScopedObjectAccess soa(Thread::Current());
+ SirtRef<ClassLoader> class_loader_1(soa.Decode<ClassLoader*>(LoadDex("MyClass")));
+ SirtRef<ClassLoader> class_loader_2(soa.Decode<ClassLoader*>(LoadDex("MyClass")));
Class* MyClass_1 = class_linker_->FindClass("LMyClass;", class_loader_1.get());
Class* MyClass_2 = class_linker_->FindClass("LMyClass;", class_loader_2.get());
EXPECT_TRUE(MyClass_1 != NULL);
@@ -834,7 +836,8 @@ TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) {
}
TEST_F(ClassLinkerTest, StaticFields) {
- SirtRef<ClassLoader> class_loader(LoadDex("Statics"));
+ ScopedObjectAccess soa(Thread::Current());
+ SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(LoadDex("Statics")));
Class* statics = class_linker_->FindClass("LStatics;", class_loader.get());
class_linker_->EnsureInitialized(statics, true, true);
@@ -915,7 +918,8 @@ TEST_F(ClassLinkerTest, StaticFields) {
}
TEST_F(ClassLinkerTest, Interfaces) {
- SirtRef<ClassLoader> class_loader(LoadDex("Interfaces"));
+ ScopedObjectAccess soa(Thread::Current());
+ SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(LoadDex("Interfaces")));
Class* I = class_linker_->FindClass("LInterfaces$I;", class_loader.get());
Class* J = class_linker_->FindClass("LInterfaces$J;", class_loader.get());
Class* K = class_linker_->FindClass("LInterfaces$K;", class_loader.get());
@@ -973,8 +977,10 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) {
// case 1, get the uninitialized storage from StaticsFromCode.<clinit>
// case 2, get the initialized storage from StaticsFromCode.getS0
- SirtRef<ClassLoader> class_loader(LoadDex("StaticsFromCode"));
- const DexFile* dex_file = Runtime::Current()->GetCompileTimeClassPath(class_loader.get())[0];
+ ScopedObjectAccess soa(Thread::Current());
+ jobject jclass_loader = LoadDex("StaticsFromCode");
+ SirtRef<ClassLoader> class_loader(soa.Decode<ClassLoader*>(jclass_loader));
+ const DexFile* dex_file = Runtime::Current()->GetCompileTimeClassPath(jclass_loader)[0];
CHECK(dex_file != NULL);
Class* klass = class_linker_->FindClass("LStaticsFromCode;", class_loader.get());
@@ -995,6 +1001,7 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) {
}
TEST_F(ClassLinkerTest, FinalizableBit) {
+ ScopedObjectAccess soa(Thread::Current());
Class* c;
// Object has a finalize method, but we know it's empty.
@@ -1028,6 +1035,7 @@ TEST_F(ClassLinkerTest, FinalizableBit) {
}
TEST_F(ClassLinkerTest, ClassRootDescriptors) {
+ ScopedObjectAccess soa(Thread::Current());
ClassHelper kh;
for (int i = 0; i < ClassLinker::kClassRootsMax; i++) {
Class* klass = class_linker_->GetClassRoot(ClassLinker::ClassRoot(i));