Merge "Get libgtest from libart-gtest."
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 43f917c..8a6d52d 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -37,6 +37,7 @@
MyClassNatives \
Nested \
NonStaticLeafMethods \
+ Packages \
ProtoCompare \
ProtoCompare2 \
ProfileTestMultiDex \
@@ -69,7 +70,7 @@
ART_GTEST_class_linker_test_DEX_DEPS := Interfaces MultiDex MyClass Nested Statics StaticsFromCode
ART_GTEST_compiler_driver_test_DEX_DEPS := AbstractMethod StaticLeafMethods ProfileTestMultiDex
-ART_GTEST_dex_cache_test_DEX_DEPS := Main
+ART_GTEST_dex_cache_test_DEX_DEPS := Main Packages
ART_GTEST_dex_file_test_DEX_DEPS := GetMethodSignature Main Nested
ART_GTEST_dex2oat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) Statics
ART_GTEST_exception_test_DEX_DEPS := ExceptionHandle
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index d1d8caa..5a5f717 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -371,8 +371,21 @@
// class rather than the declaring class itself.
DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
- // The referenced class has already been resolved with the field, get it from the dex cache.
- Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
+ // The referenced class has already been resolved with the field, but may not be in the dex
+ // cache. Using ResolveType here without handles in the caller should be safe since there
+ // should be no thread suspension due to the class being resolved.
+ // TODO: Clean this up to use handles in the caller.
+ Class* dex_access_to;
+ {
+ StackHandleScope<2> hs(Thread::Current());
+ Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer_dex_cache));
+ Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(access_to->GetClassLoader()));
+ dex_access_to = Runtime::Current()->GetClassLinker()->ResolveType(
+ *referrer_dex_cache->GetDexFile(),
+ class_idx,
+ h_dex_cache,
+ h_class_loader);
+ }
DCHECK(dex_access_to != nullptr);
if (UNLIKELY(!this->CanAccess(dex_access_to))) {
if (throw_on_failure) {
@@ -401,8 +414,21 @@
// class rather than the declaring class itself.
DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
- // The referenced class has already been resolved with the method, get it from the dex cache.
- Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
+ // The referenced class has already been resolved with the method, but may not be in the dex
+ // cache. Using ResolveType here without handles in the caller should be safe since there
+ // should be no thread suspension due to the class being resolved.
+ // TODO: Clean this up to use handles in the caller.
+ Class* dex_access_to;
+ {
+ StackHandleScope<2> hs(Thread::Current());
+ Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer_dex_cache));
+ Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(access_to->GetClassLoader()));
+ dex_access_to = Runtime::Current()->GetClassLinker()->ResolveType(
+ *referrer_dex_cache->GetDexFile(),
+ class_idx,
+ h_dex_cache,
+ h_class_loader);
+ }
DCHECK(dex_access_to != nullptr);
if (UNLIKELY(!this->CanAccess(dex_access_to))) {
if (throw_on_failure) {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 99b7769..548087e 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -1505,6 +1505,7 @@
// java.lang.Class
static GcRoot<Class> java_lang_Class_;
+ ART_FRIEND_TEST(DexCacheTest, TestResolvedFieldAccess); // For ResolvedFieldAccessTest
friend struct art::ClassOffsets; // for verifying offset information
friend class Object; // For VisitReferences
DISALLOW_IMPLICIT_CONSTRUCTORS(Class);
diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc
index 175997c..43ba362 100644
--- a/runtime/mirror/dex_cache_test.cc
+++ b/runtime/mirror/dex_cache_test.cc
@@ -64,5 +64,33 @@
EXPECT_TRUE(linear_alloc->Contains(klass->GetDexCache()->GetResolvedMethods()));
}
+TEST_F(DexCacheTest, TestResolvedFieldAccess) {
+ ScopedObjectAccess soa(Thread::Current());
+ jobject jclass_loader(LoadDex("Packages"));
+ ASSERT_TRUE(jclass_loader != nullptr);
+ Runtime* const runtime = Runtime::Current();
+ ClassLinker* const class_linker = runtime->GetClassLinker();
+ StackHandleScope<3> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
+ soa.Decode<mirror::ClassLoader*>(jclass_loader)));
+ Handle<mirror::Class> klass1 =
+ hs.NewHandle(class_linker->FindClass(soa.Self(), "Lpackage1/Package1;", class_loader));
+ ASSERT_TRUE(klass1.Get() != nullptr);
+ Handle<mirror::Class> klass2 =
+ hs.NewHandle(class_linker->FindClass(soa.Self(), "Lpackage2/Package2;", class_loader));
+ ASSERT_TRUE(klass2.Get() != nullptr);
+ EXPECT_EQ(klass1->GetDexCache(), klass2->GetDexCache());
+
+ EXPECT_NE(klass1->NumStaticFields(), 0u);
+ for (ArtField& field : klass2->GetSFields()) {
+ EXPECT_FALSE((
+ klass1->ResolvedFieldAccessTest</*throw_on_failure*/ false,
+ /*use_referrers_cache*/ false>(klass2.Get(),
+ &field,
+ field.GetDexFieldIndex(),
+ klass1->GetDexCache())));
+ }
+}
+
} // namespace mirror
} // namespace art
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 75c4f34..b554f59 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -397,9 +397,11 @@
# All these tests check that we have sane behavior if we don't have a patchoat or dex2oat.
# Therefore we shouldn't run them in situations where we actually don't have these since they
# explicitly test for them. These all also assume we have an image.
+# 004-JniTest is disabled because @CriticalNative is unsupported by generic JNI b/31400248
# 147-stripped-dex-fallback is disabled because it requires --prebuild.
# 554-jit-profile-file is disabled because it needs a primary oat file to know what it should save.
TEST_ART_BROKEN_FALLBACK_RUN_TESTS := \
+ 004-JniTest \
116-nodex2oat \
117-nopatchoat \
118-noimage-dex2oat \
@@ -473,7 +475,9 @@
# Known broken tests for the JIT.
# CFI unwinding expects managed frames, and the test does not iterate enough to even compile. JIT
# also uses Generic JNI instead of the JNI compiler.
+# 004-JniTest is disabled because @CriticalNative is unsupported by generic JNI b/31400248
TEST_ART_BROKEN_JIT_RUN_TESTS := \
+ 004-JniTest \
137-cfi
ifneq (,$(filter jit,$(COMPILER_TYPES)))
diff --git a/test/Packages/Package1.java b/test/Packages/Package1.java
new file mode 100644
index 0000000..6d58246
--- /dev/null
+++ b/test/Packages/Package1.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package package1;
+class Package1 {
+ static int someField;
+}
diff --git a/test/Packages/Package2.java b/test/Packages/Package2.java
new file mode 100644
index 0000000..9ae370a
--- /dev/null
+++ b/test/Packages/Package2.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package package2;
+class Package2 {
+ static int someField;
+}