Change iftable to never be null
Simplifies code generation by removing a null check. The null case
is rare.
Ritzperf code size: 13107624 -> 13095336
Also addressed comments from previous CL.
Bug: 32577579
Test: test-art-host, run ritzperf both with CC
Change-Id: I2b31e800867112869d7f0643e16c08826296979e
diff --git a/runtime/arch/arm/entrypoints_init_arm.cc b/runtime/arch/arm/entrypoints_init_arm.cc
index 2a12f1d..de72d3a 100644
--- a/runtime/arch/arm/entrypoints_init_arm.cc
+++ b/runtime/arch/arm/entrypoints_init_arm.cc
@@ -86,7 +86,7 @@
DefaultInitEntryPoints(jpoints, qpoints);
// Cast
- qpoints->pInstanceofNonTrivial = artInstanceOfFromCode;;
+ qpoints->pInstanceofNonTrivial = artInstanceOfFromCode;
qpoints->pCheckInstanceOf = art_quick_check_instance_of;
// Math
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 350855b..7359243 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -69,7 +69,7 @@
Thread::PoisonObjectPointersIfDebug();
ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
// MethodVerifier refuses methods with string_idx out of bounds.
- DCHECK_LT(string_idx, declaring_class->GetDexFile().NumStringIds());;
+ DCHECK_LT(string_idx, declaring_class->GetDexFile().NumStringIds());
ObjPtr<mirror::String> string =
mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(),
string_idx,
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index ac5e6aa..65e46c2 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -475,6 +475,9 @@
SetClassRoot(kJavaLangString, java_lang_String.Get());
SetClassRoot(kJavaLangRefReference, java_lang_ref_Reference.Get());
+ // Fill in the empty iftable. Needs to be done after the kObjectArrayClass root is set.
+ java_lang_Object->SetIfTable(AllocIfTable(self, 0));
+
// Setup the primitive type classes.
SetClassRoot(kPrimitiveBoolean, CreatePrimitiveClass(self, Primitive::kPrimBoolean));
SetClassRoot(kPrimitiveByte, CreatePrimitiveClass(self, Primitive::kPrimByte));
@@ -916,13 +919,11 @@
SanityCheckArtMethod(klass->GetEmbeddedVTableEntry(i, pointer_size), nullptr, image_spaces);
}
}
- auto* iftable = klass->GetIfTable();
- if (iftable != nullptr) {
- for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
- if (iftable->GetMethodArrayCount(i) > 0) {
- SanityCheckArtMethodPointerArray(
- iftable->GetMethodArray(i), nullptr, pointer_size, image_spaces);
- }
+ mirror::IfTable* iftable = klass->GetIfTable();
+ for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
+ if (iftable->GetMethodArrayCount(i) > 0) {
+ SanityCheckArtMethodPointerArray(
+ iftable->GetMethodArray(i), nullptr, pointer_size, image_spaces);
}
}
}
@@ -3401,7 +3402,8 @@
}
mirror::Class* ClassLinker::CreatePrimitiveClass(Thread* self, Primitive::Type type) {
- ObjPtr<mirror::Class> klass = AllocClass(self, mirror::Class::PrimitiveClassSize(image_pointer_size_));
+ ObjPtr<mirror::Class> klass =
+ AllocClass(self, mirror::Class::PrimitiveClassSize(image_pointer_size_));
if (UNLIKELY(klass == nullptr)) {
self->AssertPendingOOMException();
return nullptr;
@@ -3419,10 +3421,12 @@
ObjectLock<mirror::Class> lock(self, h_class);
h_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
h_class->SetPrimitiveType(type);
+ h_class->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
mirror::Class::SetStatus(h_class, mirror::Class::kStatusInitialized, self);
const char* descriptor = Primitive::Descriptor(type);
- ObjPtr<mirror::Class> existing = InsertClass(descriptor, h_class.Get(),
- ComputeModifiedUtf8Hash(descriptor));
+ ObjPtr<mirror::Class> existing = InsertClass(descriptor,
+ h_class.Get(),
+ ComputeModifiedUtf8Hash(descriptor));
CHECK(existing == nullptr) << "InitPrimitiveClass(" << type << ") failed";
return h_class.Get();
}
@@ -4121,6 +4125,8 @@
DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
klass->SetName(soa.Decode<mirror::String>(name));
klass->SetDexCache(GetClassRoot(kJavaLangReflectProxy)->GetDexCache());
+ // Object has an empty iftable, copy it for that reason.
+ klass->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
mirror::Class::SetStatus(klass, mirror::Class::kStatusIdx, self);
std::string descriptor(GetDescriptorForProxy(klass.Get()));
const size_t hash = ComputeModifiedUtf8Hash(descriptor.c_str());
@@ -6381,16 +6387,18 @@
bool ClassLinker::SetupInterfaceLookupTable(Thread* self, Handle<mirror::Class> klass,
Handle<mirror::ObjectArray<mirror::Class>> interfaces) {
StackHandleScope<1> hs(self);
- const size_t super_ifcount =
- klass->HasSuperClass() ? klass->GetSuperClass()->GetIfTableCount() : 0U;
+ const bool has_superclass = klass->HasSuperClass();
+ const size_t super_ifcount = has_superclass ? klass->GetSuperClass()->GetIfTableCount() : 0U;
const bool have_interfaces = interfaces.Get() != nullptr;
const size_t num_interfaces =
have_interfaces ? interfaces->GetLength() : klass->NumDirectInterfaces();
if (num_interfaces == 0) {
if (super_ifcount == 0) {
+ if (LIKELY(has_superclass)) {
+ klass->SetIfTable(klass->GetSuperClass()->GetIfTable());
+ }
// Class implements no interfaces.
DCHECK_EQ(klass->GetIfTableCount(), 0);
- DCHECK(klass->GetIfTable() == nullptr);
return true;
}
// Class implements same interfaces as parent, are any of these not marker interfaces?
@@ -6583,7 +6591,7 @@
} else {
// No imt in the super class, need to reconstruct from the iftable.
ObjPtr<mirror::IfTable> if_table = super_class->GetIfTable();
- if (if_table != nullptr) {
+ if (if_table->Count() != 0) {
// Ignore copied methods since we will handle these in LinkInterfaceMethods.
FillIMTFromIfTable(if_table,
unimplemented_method,
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index ab2d9d0..44590ba 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -101,7 +101,8 @@
EXPECT_EQ(0U, primitive->NumDirectInterfaces());
EXPECT_FALSE(primitive->HasVTable());
EXPECT_EQ(0, primitive->GetIfTableCount());
- EXPECT_TRUE(primitive->GetIfTable() == nullptr);
+ EXPECT_TRUE(primitive->GetIfTable() != nullptr);
+ EXPECT_EQ(primitive->GetIfTable()->Count(), 0u);
EXPECT_EQ(kAccPublic | kAccFinal | kAccAbstract, primitive->GetAccessFlags());
}
diff --git a/runtime/class_table.h b/runtime/class_table.h
index bc9eaf4..558c144 100644
--- a/runtime/class_table.h
+++ b/runtime/class_table.h
@@ -48,7 +48,7 @@
uint32_t operator()(const GcRoot<mirror::Class>& root) const NO_THREAD_SAFETY_ANALYSIS;
// Same class loader and descriptor.
bool operator()(const GcRoot<mirror::Class>& a, const GcRoot<mirror::Class>& b) const
- NO_THREAD_SAFETY_ANALYSIS;;
+ NO_THREAD_SAFETY_ANALYSIS;
// Same descriptor.
bool operator()(const GcRoot<mirror::Class>& a, const char* descriptor) const
NO_THREAD_SAFETY_ANALYSIS;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 0b602e9..6019540 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1002,7 +1002,7 @@
mirror::IfTable* iftable = as_klass->GetIfTable<kVerifyNone, kWithoutReadBarrier>();
// Ensure iftable arrays are fixed up since we need GetMethodArray to return the valid
// contents.
- if (iftable != nullptr && IsInAppImage(iftable)) {
+ if (IsInAppImage(iftable)) {
operator()(iftable);
for (int32_t i = 0, count = iftable->Count(); i < count; ++i) {
if (iftable->GetMethodArrayCount<kVerifyNone, kWithoutReadBarrier>(i) > 0) {
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index cb775cd..8c63a9e 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -1020,7 +1020,7 @@
} else {
DCHECK(!is_range);
ArtField* field = method_handle->GetTargetField();
- Primitive::Type field_type = field->GetTypeAsPrimitiveType();;
+ Primitive::Type field_type = field->GetTypeAsPrimitiveType();
switch (handle_kind) {
case kInstanceGet: {
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 2257fd6..a5b1038 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -424,7 +424,7 @@
std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
if (zip_archive == nullptr) {
- return nullptr;;
+ return nullptr;
}
std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
if (zip_entry == nullptr) {
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 4c10063..23a5ddd 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -114,7 +114,7 @@
} else {
jit_options->invoke_transition_weight_ = std::max(
jit_options->warmup_threshold_ / Jit::kDefaultInvokeTransitionWeightRatio,
- static_cast<size_t>(1));;
+ static_cast<size_t>(1));
}
return jit_options;
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index bbdb2af..9a6d60e 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -526,18 +526,17 @@
template<VerifyObjectFlags kVerifyFlags,
ReadBarrierOption kReadBarrierOption>
inline IfTable* Class::GetIfTable() {
- return GetFieldObject<IfTable, kVerifyFlags, kReadBarrierOption>(IfTableOffset());
+ ObjPtr<IfTable> ret = GetFieldObject<IfTable, kVerifyFlags, kReadBarrierOption>(IfTableOffset());
+ DCHECK(ret != nullptr) << PrettyClass(this);
+ return ret.Ptr();
}
inline int32_t Class::GetIfTableCount() {
- ObjPtr<IfTable> iftable = GetIfTable();
- if (iftable == nullptr) {
- return 0;
- }
- return iftable->Count();
+ return GetIfTable()->Count();
}
inline void Class::SetIfTable(ObjPtr<IfTable> new_iftable) {
+ DCHECK(new_iftable != nullptr) << PrettyClass(this);
SetFieldObject<false>(IfTableOffset(), new_iftable);
}
diff --git a/runtime/oat.h b/runtime/oat.h
index 3aef707..8c84d42 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@
class PACKED(4) OatHeader {
public:
static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
- static constexpr uint8_t kOatVersion[] = { '0', '9', '1', '\0' };
+ static constexpr uint8_t kOatVersion[] = { '0', '9', '2', '\0' };
static constexpr const char* kImageLocationKey = "image-location";
static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";