Clean up Class::GetDirectInterface().
Once the `klass` has been resolved, this function should not
need to resolve interface types anymore. Drop the type
resolution from this function and pass the Class as ObjPtr<>
instead of Handle<>. Make callers that expect non-null
result DCHECK() that assumption. For the callers that may
actually need to resolve these interface classes, introduce
a new function ResolveDirectInterface().
Also improve ObjPtr<> constructors and assignment operator
to improve overload resolution. For example, if we have
foo(ObjPtr<T1>) and foo(ObjPtr<T2>), calling foo(.) with
a T1* would have previously been ambiguous even if T1 is
not a base of T2.
Test: m test-art-host
Change-Id: Iff44a7285f68f0af4507fc9ba37343865422fe84
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index a2bab80..e62bdb5 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1188,13 +1188,12 @@
CHECK_NE(image_classes_->size(), 0U);
}
-static void MaybeAddToImageClasses(Handle<mirror::Class> c,
+static void MaybeAddToImageClasses(Thread* self,
+ ObjPtr<mirror::Class> klass,
std::unordered_set<std::string>* image_classes)
REQUIRES_SHARED(Locks::mutator_lock_) {
- Thread* self = Thread::Current();
+ DCHECK_EQ(self, Thread::Current());
StackHandleScope<1> hs(self);
- // Make a copy of the handle so that we don't clobber it doing Assign.
- MutableHandle<mirror::Class> klass(hs.NewHandle(c.Get()));
std::string temp;
const PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
while (!klass->IsObjectClass()) {
@@ -1205,19 +1204,16 @@
break;
}
VLOG(compiler) << "Adding " << descriptor << " to image classes";
- for (size_t i = 0; i < klass->NumDirectInterfaces(); ++i) {
- StackHandleScope<1> hs2(self);
- // May cause thread suspension.
- MaybeAddToImageClasses(hs2.NewHandle(mirror::Class::GetDirectInterface(self, klass, i)),
- image_classes);
+ for (size_t i = 0, num_interfaces = klass->NumDirectInterfaces(); i != num_interfaces; ++i) {
+ ObjPtr<mirror::Class> interface = mirror::Class::GetDirectInterface(self, klass, i);
+ DCHECK(interface != nullptr);
+ MaybeAddToImageClasses(self, interface, image_classes);
}
- for (auto& m : c->GetVirtualMethods(pointer_size)) {
- StackHandleScope<1> hs2(self);
- MaybeAddToImageClasses(hs2.NewHandle(m.GetDeclaringClass()), image_classes);
+ for (auto& m : klass->GetVirtualMethods(pointer_size)) {
+ MaybeAddToImageClasses(self, m.GetDeclaringClass(), image_classes);
}
if (klass->IsArrayClass()) {
- StackHandleScope<1> hs2(self);
- MaybeAddToImageClasses(hs2.NewHandle(klass->GetComponentType()), image_classes);
+ MaybeAddToImageClasses(self, klass->GetComponentType(), image_classes);
}
klass.Assign(klass->GetSuperClass());
}
@@ -1268,8 +1264,10 @@
for (Handle<mirror::Class> klass_root : image_classes_) {
VisitClinitClassesObject(klass_root.Get());
}
+ Thread* self = Thread::Current();
+ ScopedAssertNoThreadSuspension ants(__FUNCTION__);
for (Handle<mirror::Class> h_klass : to_insert_) {
- MaybeAddToImageClasses(h_klass, image_class_descriptors_);
+ MaybeAddToImageClasses(self, h_klass.Get(), image_class_descriptors_);
}
}
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 319991b..92c682d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -629,13 +629,13 @@
// Sanity check Class[] and Object[]'s interfaces. GetDirectInterface may cause thread
// suspension.
CHECK_EQ(java_lang_Cloneable.Get(),
- mirror::Class::GetDirectInterface(self, class_array_class, 0));
+ mirror::Class::GetDirectInterface(self, class_array_class.Get(), 0));
CHECK_EQ(java_io_Serializable.Get(),
- mirror::Class::GetDirectInterface(self, class_array_class, 1));
+ mirror::Class::GetDirectInterface(self, class_array_class.Get(), 1));
CHECK_EQ(java_lang_Cloneable.Get(),
- mirror::Class::GetDirectInterface(self, object_array_class, 0));
+ mirror::Class::GetDirectInterface(self, object_array_class.Get(), 0));
CHECK_EQ(java_io_Serializable.Get(),
- mirror::Class::GetDirectInterface(self, object_array_class, 1));
+ mirror::Class::GetDirectInterface(self, object_array_class.Get(), 1));
CHECK_EQ(object_array_string.Get(),
FindSystemClass(self, GetClassRootDescriptor(kJavaLangStringArrayClass)));
@@ -4486,7 +4486,7 @@
StackHandleScope<1> hs_iface(self);
MutableHandle<mirror::Class> handle_scope_iface(hs_iface.NewHandle<mirror::Class>(nullptr));
for (size_t i = 0; i < num_direct_interfaces; i++) {
- handle_scope_iface.Assign(mirror::Class::GetDirectInterface(self, klass, i));
+ handle_scope_iface.Assign(mirror::Class::GetDirectInterface(self, klass.Get(), i));
CHECK(handle_scope_iface.Get() != nullptr);
CHECK(handle_scope_iface->IsInterface());
if (handle_scope_iface->HasBeenRecursivelyInitialized()) {
@@ -4622,7 +4622,8 @@
MutableHandle<mirror::Class> handle_super_iface(hs.NewHandle<mirror::Class>(nullptr));
// First we initialize all of iface's super-interfaces recursively.
for (size_t i = 0; i < num_direct_ifaces; i++) {
- ObjPtr<mirror::Class> super_iface = mirror::Class::GetDirectInterface(self, iface, i);
+ ObjPtr<mirror::Class> super_iface = mirror::Class::GetDirectInterface(self, iface.Get(), i);
+ DCHECK(super_iface != nullptr);
if (!super_iface->HasBeenRecursivelyInitialized()) {
// Recursive step
handle_super_iface.Assign(super_iface);
@@ -6383,7 +6384,7 @@
for (size_t i = 0; i < num_interfaces; i++) {
ObjPtr<mirror::Class> interface = have_interfaces
? interfaces->GetWithoutChecks(i)
- : mirror::Class::GetDirectInterface(self, klass, i);
+ : mirror::Class::GetDirectInterface(self, klass.Get(), i);
DCHECK(interface != nullptr);
if (UNLIKELY(!interface->IsInterface())) {
std::string temp;
@@ -6421,7 +6422,7 @@
std::vector<mirror::Class*> to_add;
for (size_t i = 0; i < num_interfaces; i++) {
ObjPtr<mirror::Class> interface = have_interfaces ? interfaces->Get(i) :
- mirror::Class::GetDirectInterface(self, klass, i);
+ mirror::Class::GetDirectInterface(self, klass.Get(), i);
to_add.push_back(interface.Ptr());
}
@@ -7796,16 +7797,14 @@
}
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
Thread* const self = Thread::Current();
- StackHandleScope<1> hs(self);
- Handle<mirror::Class> klass(
- hs.NewHandle(ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader)));
- if (klass.Get() == nullptr) {
+ ObjPtr<mirror::Class> klass = ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader);
+ if (klass == nullptr) {
DCHECK(Thread::Current()->IsExceptionPending());
return nullptr;
}
if (is_static) {
- resolved = mirror::Class::FindStaticField(self, klass.Get(), dex_cache.Get(), field_idx);
+ resolved = mirror::Class::FindStaticField(self, klass, dex_cache.Get(), field_idx);
} else {
resolved = klass->FindInstanceField(dex_cache.Get(), field_idx);
}
@@ -7819,7 +7818,7 @@
resolved = klass->FindInstanceField(name, type);
}
if (resolved == nullptr) {
- ThrowNoSuchFieldError(is_static ? "static " : "instance ", klass.Get(), type, name);
+ ThrowNoSuchFieldError(is_static ? "static " : "instance ", klass, type, name);
return nullptr;
}
}
@@ -7839,10 +7838,8 @@
}
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
Thread* self = Thread::Current();
- StackHandleScope<1> hs(self);
- Handle<mirror::Class> klass(
- hs.NewHandle(ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader)));
- if (klass.Get() == nullptr) {
+ ObjPtr<mirror::Class> klass(ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader));
+ if (klass == nullptr) {
DCHECK(Thread::Current()->IsExceptionPending());
return nullptr;
}
@@ -7854,7 +7851,7 @@
if (resolved != nullptr) {
dex_cache->SetResolvedField(field_idx, resolved, image_pointer_size_);
} else {
- ThrowNoSuchFieldError("", klass.Get(), type, name);
+ ThrowNoSuchFieldError("", klass, type, name);
}
return resolved;
}
@@ -8078,7 +8075,7 @@
ScopedObjectAccessUnchecked soa(self);
// For now, create a libcore-level DexFile for each ART DexFile. This "explodes" multidex.
- StackHandleScope<11> hs(self);
+ StackHandleScope<6> hs(self);
ArtField* dex_elements_field =
jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements);
@@ -8157,7 +8154,9 @@
// Make a pretend boot-classpath.
// TODO: Should we scan the image?
ArtField* const parent_field =
- mirror::Class::FindField(self, hs.NewHandle(h_path_class_loader->GetClass()), "parent",
+ mirror::Class::FindField(self,
+ h_path_class_loader->GetClass(),
+ "parent",
"Ljava/lang/ClassLoader;");
DCHECK(parent_field != nullptr);
ObjPtr<mirror::Object> boot_cl =
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index ddb9e59..862585a 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -215,10 +215,12 @@
EXPECT_TRUE(array->ShouldHaveEmbeddedVTable());
EXPECT_EQ(2, array->GetIfTableCount());
ASSERT_TRUE(array->GetIfTable() != nullptr);
- ObjPtr<mirror::Class> direct_interface0 = mirror::Class::GetDirectInterface(self, array, 0);
+ ObjPtr<mirror::Class> direct_interface0 =
+ mirror::Class::GetDirectInterface(self, array.Get(), 0);
EXPECT_TRUE(direct_interface0 != nullptr);
EXPECT_STREQ(direct_interface0->GetDescriptor(&temp), "Ljava/lang/Cloneable;");
- ObjPtr<mirror::Class> direct_interface1 = mirror::Class::GetDirectInterface(self, array, 1);
+ ObjPtr<mirror::Class> direct_interface1 =
+ mirror::Class::GetDirectInterface(self, array.Get(), 1);
EXPECT_STREQ(direct_interface1->GetDescriptor(&temp), "Ljava/io/Serializable;");
ObjPtr<mirror::Class> array_ptr = array->GetComponentType();
EXPECT_OBJ_PTR_EQ(class_linker_->FindArrayClass(self, &array_ptr), array.Get());
@@ -1019,48 +1021,48 @@
EXPECT_EQ(9U, statics->NumStaticFields());
- ArtField* s0 = mirror::Class::FindStaticField(soa.Self(), statics, "s0", "Z");
+ ArtField* s0 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s0", "Z");
EXPECT_EQ(s0->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
EXPECT_EQ(true, s0->GetBoolean(statics.Get()));
s0->SetBoolean<false>(statics.Get(), false);
- ArtField* s1 = mirror::Class::FindStaticField(soa.Self(), statics, "s1", "B");
+ ArtField* s1 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s1", "B");
EXPECT_EQ(s1->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
EXPECT_EQ(5, s1->GetByte(statics.Get()));
s1->SetByte<false>(statics.Get(), 6);
- ArtField* s2 = mirror::Class::FindStaticField(soa.Self(), statics, "s2", "C");
+ ArtField* s2 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s2", "C");
EXPECT_EQ(s2->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
EXPECT_EQ('a', s2->GetChar(statics.Get()));
s2->SetChar<false>(statics.Get(), 'b');
- ArtField* s3 = mirror::Class::FindStaticField(soa.Self(), statics, "s3", "S");
+ ArtField* s3 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s3", "S");
EXPECT_EQ(s3->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
EXPECT_EQ(-536, s3->GetShort(statics.Get()));
s3->SetShort<false>(statics.Get(), -535);
- ArtField* s4 = mirror::Class::FindStaticField(soa.Self(), statics, "s4", "I");
+ ArtField* s4 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s4", "I");
EXPECT_EQ(s4->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
EXPECT_EQ(2000000000, s4->GetInt(statics.Get()));
s4->SetInt<false>(statics.Get(), 2000000001);
- ArtField* s5 = mirror::Class::FindStaticField(soa.Self(), statics, "s5", "J");
+ ArtField* s5 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s5", "J");
EXPECT_EQ(s5->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong(statics.Get()));
s5->SetLong<false>(statics.Get(), INT64_C(0x34567890abcdef12));
- ArtField* s6 = mirror::Class::FindStaticField(soa.Self(), statics, "s6", "F");
+ ArtField* s6 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s6", "F");
EXPECT_EQ(s6->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
EXPECT_DOUBLE_EQ(0.5, s6->GetFloat(statics.Get()));
s6->SetFloat<false>(statics.Get(), 0.75);
- ArtField* s7 = mirror::Class::FindStaticField(soa.Self(), statics, "s7", "D");
+ ArtField* s7 = mirror::Class::FindStaticField(soa.Self(), statics.Get(), "s7", "D");
EXPECT_EQ(s7->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
EXPECT_DOUBLE_EQ(16777217.0, s7->GetDouble(statics.Get()));
s7->SetDouble<false>(statics.Get(), 16777219);
- ArtField* s8 = mirror::Class::FindStaticField(soa.Self(), statics, "s8",
- "Ljava/lang/String;");
+ ArtField* s8 = mirror::Class::FindStaticField(
+ soa.Self(), statics.Get(), "s8", "Ljava/lang/String;");
EXPECT_EQ(s8->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("android"));
mirror::String* str_value = mirror::String::AllocFromModifiedUtf8(soa.Self(), "robot");
@@ -1131,10 +1133,14 @@
EXPECT_EQ(Aj1, A->FindVirtualMethodForVirtualOrInterface(Jj1, kRuntimePointerSize));
EXPECT_EQ(Aj2, A->FindVirtualMethodForVirtualOrInterface(Jj2, kRuntimePointerSize));
- ArtField* Afoo = mirror::Class::FindStaticField(soa.Self(), A, "foo", "Ljava/lang/String;");
- ArtField* Bfoo = mirror::Class::FindStaticField(soa.Self(), B, "foo", "Ljava/lang/String;");
- ArtField* Jfoo = mirror::Class::FindStaticField(soa.Self(), J, "foo", "Ljava/lang/String;");
- ArtField* Kfoo = mirror::Class::FindStaticField(soa.Self(), K, "foo", "Ljava/lang/String;");
+ ArtField* Afoo =
+ mirror::Class::FindStaticField(soa.Self(), A.Get(), "foo", "Ljava/lang/String;");
+ ArtField* Bfoo =
+ mirror::Class::FindStaticField(soa.Self(), B.Get(), "foo", "Ljava/lang/String;");
+ ArtField* Jfoo =
+ mirror::Class::FindStaticField(soa.Self(), J.Get(), "foo", "Ljava/lang/String;");
+ ArtField* Kfoo =
+ mirror::Class::FindStaticField(soa.Self(), K.Get(), "foo", "Ljava/lang/String;");
ASSERT_TRUE(Afoo != nullptr);
EXPECT_EQ(Afoo, Bfoo);
EXPECT_EQ(Afoo, Jfoo);
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index dc2ae2e..e339666 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1565,16 +1565,16 @@
JDWP::JdwpError Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply) {
JDWP::JdwpError error;
Thread* self = Thread::Current();
- StackHandleScope<1> hs(self);
- Handle<mirror::Class> c(hs.NewHandle(DecodeClass(class_id, &error)));
- if (c.Get() == nullptr) {
+ ObjPtr<mirror::Class> c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
return error;
}
size_t interface_count = c->NumDirectInterfaces();
expandBufAdd4BE(pReply, interface_count);
for (size_t i = 0; i < interface_count; ++i) {
- expandBufAddRefTypeId(pReply,
- gRegistry->AddRefType(mirror::Class::GetDirectInterface(self, c, i)));
+ ObjPtr<mirror::Class> interface = mirror::Class::GetDirectInterface(self, c, i);
+ DCHECK(interface != nullptr);
+ expandBufAddRefTypeId(pReply, gRegistry->AddRefType(interface));
}
return JDWP::ERR_NONE;
}
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 01a2ad8..3c641b0 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -224,8 +224,8 @@
}
std::string temp;
if (is_static) {
- field = mirror::Class::FindStaticField(soa.Self(), c, name,
- field_type->GetDescriptor(&temp));
+ field = mirror::Class::FindStaticField(
+ soa.Self(), c.Get(), name, field_type->GetDescriptor(&temp));
} else {
field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
}
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 0cfe29b..a862c97 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -276,7 +276,7 @@
if (num_direct_interfaces > 0) {
os << " interfaces (" << num_direct_interfaces << "):\n";
for (size_t i = 0; i < num_direct_interfaces; ++i) {
- ObjPtr<Class> interface = GetDirectInterface(self, h_this, i);
+ ObjPtr<Class> interface = GetDirectInterface(self, h_this.Get(), i);
if (interface == nullptr) {
os << StringPrintf(" %2zd: nullptr!\n", i);
} else {
@@ -799,24 +799,21 @@
}
ArtField* Class::FindStaticField(Thread* self,
- Handle<Class> klass,
+ ObjPtr<Class> klass,
const StringPiece& name,
const StringPiece& type) {
// Is the field in this class (or its interfaces), or any of its
// superclasses (or their interfaces)?
- for (ObjPtr<Class> k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
+ for (ObjPtr<Class> k = klass; k != nullptr; k = k->GetSuperClass()) {
// Is the field in this class?
ArtField* f = k->FindDeclaredStaticField(name, type);
if (f != nullptr) {
return f;
}
- // Wrap k incase it moves during GetDirectInterface.
- StackHandleScope<1> hs(self);
- HandleWrapperObjPtr<Class> h_k(hs.NewHandleWrapper(&k));
// Is this field in any of this class' interfaces?
- for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
- StackHandleScope<1> hs2(self);
- Handle<Class> interface(hs2.NewHandle(GetDirectInterface(self, h_k, i)));
+ for (uint32_t i = 0, num_interfaces = k->NumDirectInterfaces(); i != num_interfaces; ++i) {
+ ObjPtr<Class> interface = GetDirectInterface(self, k, i);
+ DCHECK(interface != nullptr);
f = FindStaticField(self, interface, name, type);
if (f != nullptr) {
return f;
@@ -839,11 +836,10 @@
// Though GetDirectInterface() should not cause thread suspension when called
// from here, it takes a Handle as an argument, so we need to wrap `k`.
ScopedAssertNoThreadSuspension ants(__FUNCTION__);
- StackHandleScope<1> hs(self);
- Handle<Class> h_k(hs.NewHandle(k));
// Is this field in any of this class' interfaces?
- for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
- ObjPtr<Class> interface = GetDirectInterface(self, h_k, i);
+ for (uint32_t i = 0, num_interfaces = k->NumDirectInterfaces(); i != num_interfaces; ++i) {
+ ObjPtr<Class> interface = GetDirectInterface(self, k, i);
+ DCHECK(interface != nullptr);
f = FindStaticField(self, interface, dex_cache, dex_field_idx);
if (f != nullptr) {
return f;
@@ -854,11 +850,11 @@
}
ArtField* Class::FindField(Thread* self,
- Handle<Class> klass,
+ ObjPtr<Class> klass,
const StringPiece& name,
const StringPiece& type) {
// Find a field using the JLS field resolution order
- for (ObjPtr<Class> k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
+ for (ObjPtr<Class> k = klass; k != nullptr; k = k->GetSuperClass()) {
// Is the field in this class?
ArtField* f = k->FindDeclaredInstanceField(name, type);
if (f != nullptr) {
@@ -869,12 +865,10 @@
return f;
}
// Is this field in any of this class' interfaces?
- StackHandleScope<1> hs(self);
- HandleWrapperObjPtr<Class> h_k(hs.NewHandleWrapper(&k));
- for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
- StackHandleScope<1> hs2(self);
- Handle<Class> interface(hs2.NewHandle(GetDirectInterface(self, h_k, i)));
- f = interface->FindStaticField(self, interface, name, type);
+ for (uint32_t i = 0, num_interfaces = k->NumDirectInterfaces(); i != num_interfaces; ++i) {
+ ObjPtr<Class> interface = GetDirectInterface(self, k, i);
+ DCHECK(interface != nullptr);
+ f = FindStaticField(self, interface, name, type);
if (f != nullptr) {
return f;
}
@@ -929,36 +923,46 @@
return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
}
-ObjPtr<Class> Class::GetDirectInterface(Thread* self,
- Handle<Class> klass,
- uint32_t idx) {
- DCHECK(klass.Get() != nullptr);
+ObjPtr<Class> Class::GetDirectInterface(Thread* self, ObjPtr<Class> klass, uint32_t idx) {
+ DCHECK(klass != nullptr);
DCHECK(!klass->IsPrimitive());
if (klass->IsArrayClass()) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ // Use ClassLinker::LookupClass(); avoid poisoning ObjPtr<>s by ClassLinker::FindSystemClass().
+ ObjPtr<Class> interface;
if (idx == 0) {
- return class_linker->FindSystemClass(self, "Ljava/lang/Cloneable;");
+ interface = class_linker->LookupClass(self, "Ljava/lang/Cloneable;", nullptr);
} else {
DCHECK_EQ(1U, idx);
- return class_linker->FindSystemClass(self, "Ljava/io/Serializable;");
+ interface = class_linker->LookupClass(self, "Ljava/io/Serializable;", nullptr);
}
+ DCHECK(interface != nullptr);
+ return interface;
} else if (klass->IsProxyClass()) {
- ObjPtr<ObjectArray<Class>> interfaces = klass.Get()->GetInterfaces();
+ ObjPtr<ObjectArray<Class>> interfaces = klass->GetInterfaces();
DCHECK(interfaces != nullptr);
return interfaces->Get(idx);
} else {
dex::TypeIndex type_idx = klass->GetDirectInterfaceTypeIdx(idx);
ObjPtr<Class> interface = klass->GetDexCache()->GetResolvedType(type_idx);
- if (interface == nullptr) {
- interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(),
- type_idx,
- klass.Get());
- CHECK(interface != nullptr || self->IsExceptionPending());
- }
return interface;
}
}
+ObjPtr<Class> Class::ResolveDirectInterface(Thread* self, Handle<Class> klass, uint32_t idx) {
+ ObjPtr<Class> interface = GetDirectInterface(self, klass.Get(), idx);
+ if (interface == nullptr) {
+ DCHECK(!klass->IsArrayClass());
+ DCHECK(!klass->IsProxyClass());
+ dex::TypeIndex type_idx = klass->GetDirectInterfaceTypeIdx(idx);
+ interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(),
+ type_idx,
+ klass.Get());
+ CHECK(interface != nullptr || self->IsExceptionPending());
+ }
+ return interface;
+}
+
ObjPtr<Class> Class::GetCommonSuperClass(Handle<Class> klass) {
DCHECK(klass.Get() != nullptr);
DCHECK(!klass->IsInterface());
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 248c941..d7449c8 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -1087,7 +1087,9 @@
ArtField* GetStaticField(uint32_t i) REQUIRES_SHARED(Locks::mutator_lock_);
// Find a static or instance field using the JLS resolution order
- static ArtField* FindField(Thread* self, Handle<Class> klass, const StringPiece& name,
+ static ArtField* FindField(Thread* self,
+ ObjPtr<Class> klass,
+ const StringPiece& name,
const StringPiece& type)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -1108,7 +1110,7 @@
// Finds the given static field in this class or a superclass.
static ArtField* FindStaticField(Thread* self,
- Handle<Class> klass,
+ ObjPtr<Class> klass,
const StringPiece& name,
const StringPiece& type)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -1204,9 +1206,15 @@
dex::TypeIndex GetDirectInterfaceTypeIdx(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_);
- static ObjPtr<Class> GetDirectInterface(Thread* self,
- Handle<Class> klass,
- uint32_t idx)
+ // Get the direct interface of the `klass` at index `idx` if resolved, otherwise return null.
+ // If the caller expects the interface to be resolved, for example for a resolved `klass`,
+ // that assumption should be checked by `DCHECK(result != nullptr)`.
+ static ObjPtr<Class> GetDirectInterface(Thread* self, ObjPtr<Class> klass, uint32_t idx)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
+ // Resolve and get the direct interface of the `klass` at index `idx`.
+ // Returns null with a pending exception if the resolution fails.
+ static ObjPtr<Class> ResolveDirectInterface(Thread* self, Handle<Class> klass, uint32_t idx)
REQUIRES_SHARED(Locks::mutator_lock_);
const char* GetSourceFile() REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 4b47f7f..a6f56ae 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -140,9 +140,9 @@
Handle<mirror::Class> klass(hs.NewHandle(oa->GetClass()));
ASSERT_EQ(2U, klass->NumDirectInterfaces());
EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;"),
- mirror::Class::GetDirectInterface(soa.Self(), klass, 0));
+ mirror::Class::GetDirectInterface(soa.Self(), klass.Get(), 0));
EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;"),
- mirror::Class::GetDirectInterface(soa.Self(), klass, 1));
+ mirror::Class::GetDirectInterface(soa.Self(), klass.Get(), 1));
}
TEST_F(ObjectTest, AllocArray) {
@@ -708,19 +708,19 @@
// Wrong type.
EXPECT_TRUE(c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "I") == nullptr);
EXPECT_TRUE(mirror::Class::FindStaticField(
- soa.Self(), c, "CASE_INSENSITIVE_ORDER", "I") == nullptr);
+ soa.Self(), c.Get(), "CASE_INSENSITIVE_ORDER", "I") == nullptr);
// Wrong name.
EXPECT_TRUE(c->FindDeclaredStaticField(
"cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == nullptr);
EXPECT_TRUE(
- mirror::Class::FindStaticField(soa.Self(), c, "cASE_INSENSITIVE_ORDER",
- "Ljava/util/Comparator;") == nullptr);
+ mirror::Class::FindStaticField(
+ soa.Self(), c.Get(), "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == nullptr);
// Right name and type.
ArtField* f1 = c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
- ArtField* f2 = mirror::Class::FindStaticField(soa.Self(), c, "CASE_INSENSITIVE_ORDER",
- "Ljava/util/Comparator;");
+ ArtField* f2 = mirror::Class::FindStaticField(
+ soa.Self(), c.Get(), "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
EXPECT_TRUE(f1 != nullptr);
EXPECT_TRUE(f2 != nullptr);
EXPECT_EQ(f1, f2);
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 642826c..3341f53 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -278,7 +278,7 @@
uint32_t num_direct_interfaces = h_clazz->NumDirectInterfaces();
for (uint32_t i = 0; i < num_direct_interfaces; i++) {
- ObjPtr<mirror::Class> iface = mirror::Class::GetDirectInterface(self, h_clazz, i);
+ ObjPtr<mirror::Class> iface = mirror::Class::ResolveDirectInterface(self, h_clazz, i);
if (UNLIKELY(iface == nullptr)) {
self->AssertPendingException();
return nullptr;
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 5730cf2..94c12af 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -1297,7 +1297,7 @@
for (std::pair<OatFileAssistant::DexOptNeeded, const char*> field : mapping) {
ArtField* art_field = mirror::Class::FindStaticField(
- soa.Self(), dexfile, field.second, "I");
+ soa.Self(), dexfile.Get(), field.second, "I");
ASSERT_FALSE(art_field == nullptr);
EXPECT_EQ(art_field->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
EXPECT_EQ(field.first, art_field->GetInt(dexfile.Get()));
diff --git a/runtime/obj_ptr.h b/runtime/obj_ptr.h
index d24c6fb..2da2ae5 100644
--- a/runtime/obj_ptr.h
+++ b/runtime/obj_ptr.h
@@ -51,27 +51,24 @@
REQUIRES_SHARED(Locks::mutator_lock_)
: reference_(0u) {}
- template <typename Type>
+ template <typename Type,
+ typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type>
ALWAYS_INLINE ObjPtr(Type* ptr) // NOLINT
REQUIRES_SHARED(Locks::mutator_lock_)
: reference_(Encode(static_cast<MirrorType*>(ptr))) {
- static_assert(std::is_base_of<MirrorType, Type>::value,
- "Input type must be a subtype of the ObjPtr type");
}
- template <typename Type>
+ template <typename Type,
+ typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type>
ALWAYS_INLINE ObjPtr(const ObjPtr<Type, kPoison>& other) // NOLINT
REQUIRES_SHARED(Locks::mutator_lock_)
: reference_(Encode(static_cast<MirrorType*>(other.Ptr()))) {
- static_assert(std::is_base_of<MirrorType, Type>::value,
- "Input type must be a subtype of the ObjPtr type");
}
- template <typename Type>
+ template <typename Type,
+ typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type>
ALWAYS_INLINE ObjPtr& operator=(const ObjPtr<Type, kPoison>& other)
REQUIRES_SHARED(Locks::mutator_lock_) {
- static_assert(std::is_base_of<MirrorType, Type>::value,
- "Input type must be a subtype of the ObjPtr type");
reference_ = Encode(static_cast<MirrorType*>(other.Ptr()));
return *this;
}
diff --git a/runtime/openjdkjvmti/ti_heap.cc b/runtime/openjdkjvmti/ti_heap.cc
index 5e588a8..5f18b7c 100644
--- a/runtime/openjdkjvmti/ti_heap.cc
+++ b/runtime/openjdkjvmti/ti_heap.cc
@@ -484,7 +484,7 @@
art::Handle<art::mirror::Class> h_klass(hs.NewHandle<art::mirror::Class>(klass));
for (size_t i = 0; i < h_klass->NumDirectInterfaces(); ++i) {
art::ObjPtr<art::mirror::Class> inf_klass =
- art::mirror::Class::GetDirectInterface(self, h_klass, i);
+ art::mirror::Class::ResolveDirectInterface(self, h_klass, i);
if (inf_klass == nullptr) {
// TODO: With a resolved class this should not happen...
self->ClearException();
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index fd7e56d..1292a81 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -128,8 +128,8 @@
ASSERT_TRUE(proxy_class->IsInitialized());
EXPECT_EQ(2U, proxy_class->NumDirectInterfaces()); // Interfaces$I and Interfaces$J.
- EXPECT_OBJ_PTR_EQ(I.Get(), mirror::Class::GetDirectInterface(soa.Self(), proxy_class, 0));
- EXPECT_OBJ_PTR_EQ(J.Get(), mirror::Class::GetDirectInterface(soa.Self(), proxy_class, 1));
+ EXPECT_OBJ_PTR_EQ(I.Get(), mirror::Class::GetDirectInterface(soa.Self(), proxy_class.Get(), 0));
+ EXPECT_OBJ_PTR_EQ(J.Get(), mirror::Class::GetDirectInterface(soa.Self(), proxy_class.Get(), 1));
std::string temp;
const char* proxy_class_descriptor = proxy_class->GetDescriptor(&temp);
EXPECT_STREQ("L$Proxy1234;", proxy_class_descriptor);