diff options
author | 2024-11-28 16:28:04 +0000 | |
---|---|---|
committer | 2025-01-16 11:36:58 +0000 | |
commit | 990cf07523a5c6ae437a0bd0cc80fb63320def5e (patch) | |
tree | 7d7160e014b14368c6cd8dcfcbfe9e2996f19e51 /runtime/class_linker.cc | |
parent | ae13bd8a14183069642a5eed4793cf34f5a2eadc (diff) |
Merge sFields and iFields.
Test: test.py
Change-Id: Ib97fca637a8866a41a4389b150c6000d9fb6d99b
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 140 |
1 files changed, 71 insertions, 69 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 1488cc6450..31d3acbbcd 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1102,23 +1102,29 @@ void ClassLinker::FinishInit(Thread* self) { Handle<mirror::Class> java_lang_ref_FinalizerReference = hs.NewHandle(FindSystemClass(self, "Ljava/lang/ref/FinalizerReference;")); - ArtField* pendingNext = java_lang_ref_Reference->GetInstanceField(0); + ArtField* pendingNext = java_lang_ref_Reference->GetField(1); + CHECK(!pendingNext->IsStatic()); CHECK_STREQ(pendingNext->GetName(), "pendingNext"); CHECK_STREQ(pendingNext->GetTypeDescriptor(), "Ljava/lang/ref/Reference;"); - ArtField* queue = java_lang_ref_Reference->GetInstanceField(1); + ArtField* queue = java_lang_ref_Reference->GetField(2); + CHECK(!queue->IsStatic()); CHECK_STREQ(queue->GetName(), "queue"); CHECK_STREQ(queue->GetTypeDescriptor(), "Ljava/lang/ref/ReferenceQueue;"); - ArtField* queueNext = java_lang_ref_Reference->GetInstanceField(2); + ArtField* queueNext = java_lang_ref_Reference->GetField(3); + CHECK(!queueNext->IsStatic()); CHECK_STREQ(queueNext->GetName(), "queueNext"); CHECK_STREQ(queueNext->GetTypeDescriptor(), "Ljava/lang/ref/Reference;"); - ArtField* referent = java_lang_ref_Reference->GetInstanceField(3); + ArtField* referent = java_lang_ref_Reference->GetField(4); + CHECK(!referent->IsStatic()); CHECK_STREQ(referent->GetName(), "referent"); CHECK_STREQ(referent->GetTypeDescriptor(), "Ljava/lang/Object;"); - ArtField* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2); + ArtField* zombie = java_lang_ref_FinalizerReference->GetField( + java_lang_ref_FinalizerReference->NumFields() - 1); + CHECK(!zombie->IsStatic()); CHECK_STREQ(zombie->GetName(), "zombie"); CHECK_STREQ(zombie->GetTypeDescriptor(), "Ljava/lang/Object;"); @@ -2003,10 +2009,7 @@ class ImageChecker final { CHECK(class_class != nullptr) << "Null class class " << obj; if (obj_klass == class_class) { auto klass = obj->AsClass(); - for (ArtField& field : klass->GetIFields()) { - CHECK_EQ(field.GetDeclaringClass<kWithoutReadBarrier>(), klass); - } - for (ArtField& field : klass->GetSFields()) { + for (ArtField& field : klass->GetFields()) { CHECK_EQ(field.GetDeclaringClass<kWithoutReadBarrier>(), klass); } for (ArtMethod& m : klass->GetMethods(kPointerSize)) { @@ -4019,12 +4022,11 @@ void ClassLinker::LoadClass(Thread* self, // We allow duplicate definitions of the same field in a class_data_item // but ignore the repeated indexes here, b/21868015. LinearAlloc* const allocator = GetAllocatorForClassLoader(klass->GetClassLoader()); - LengthPrefixedArray<ArtField>* sfields = AllocArtFieldArray(self, - allocator, - accessor.NumStaticFields()); - LengthPrefixedArray<ArtField>* ifields = AllocArtFieldArray(self, - allocator, - accessor.NumInstanceFields()); + LengthPrefixedArray<ArtField>* fields = + AllocArtFieldArray(self, + allocator, + accessor.NumStaticFields() + accessor.NumInstanceFields()); + size_t num_fields = 0u; size_t num_sfields = 0u; size_t num_ifields = 0u; uint32_t last_static_field_idx = 0u; @@ -4056,7 +4058,8 @@ void ClassLinker::LoadClass(Thread* self, uint32_t field_idx = field.GetIndex(); DCHECK_GE(field_idx, last_static_field_idx); // Ordering enforced by DexFileVerifier. if (num_sfields == 0 || LIKELY(field_idx > last_static_field_idx)) { - LoadField(field, klass, &sfields->At(num_sfields)); + LoadField(field, klass, &fields->At(num_fields)); + ++num_fields; ++num_sfields; last_static_field_idx = field_idx; } @@ -4064,7 +4067,8 @@ void ClassLinker::LoadClass(Thread* self, uint32_t field_idx = field.GetIndex(); DCHECK_GE(field_idx, last_instance_field_idx); // Ordering enforced by DexFileVerifier. if (num_ifields == 0 || LIKELY(field_idx > last_instance_field_idx)) { - LoadField(field, klass, &ifields->At(num_ifields)); + LoadField(field, klass, &fields->At(num_fields)); + ++num_fields; ++num_ifields; last_instance_field_idx = field_idx; } @@ -4094,24 +4098,27 @@ void ClassLinker::LoadClass(Thread* self, ++class_def_method_index; }); - if (UNLIKELY(num_ifields + num_sfields != accessor.NumFields())) { + if (UNLIKELY(num_fields != accessor.NumFields())) { LOG(WARNING) << "Duplicate fields in class " << klass->PrettyDescriptor() << " (unique static fields: " << num_sfields << "/" << accessor.NumStaticFields() << ", unique instance fields: " << num_ifields << "/" << accessor.NumInstanceFields() << ")"; - // NOTE: Not shrinking the over-allocated sfields/ifields, just setting size. - if (sfields != nullptr) { - sfields->SetSize(num_sfields); - } - if (ifields != nullptr) { - ifields->SetSize(num_ifields); + // NOTE: Not shrinking the over-allocated fields, just setting size. + if (fields != nullptr) { + fields->SetSize(num_fields); } } - // Set the field arrays. - klass->SetSFieldsPtr(sfields); - DCHECK_EQ(klass->NumStaticFields(), num_sfields); - klass->SetIFieldsPtr(ifields); - DCHECK_EQ(klass->NumInstanceFields(), num_ifields); + if (fields != nullptr) { + // Sort the fields by dex field index to facilitate fast lookups. + std::sort(fields->begin(), + fields->end(), + [](ArtField& lhs, ArtField& rhs) { + return lhs.GetDexFieldIndex() < rhs.GetDexFieldIndex(); + }); + } + + // Set the field array. + klass->SetFieldsPtr(fields); } // Ensure that the card is marked so that remembered sets pick up native roots. WriteBarrier::ForEveryFieldWrite(klass.Get()); @@ -5304,18 +5311,18 @@ ObjPtr<mirror::Class> ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRun // Instance fields are inherited, but we add a couple of static fields... const size_t num_fields = 2; - LengthPrefixedArray<ArtField>* sfields = AllocArtFieldArray(self, allocator, num_fields); - temp_klass->SetSFieldsPtr(sfields); + LengthPrefixedArray<ArtField>* fields = AllocArtFieldArray(self, allocator, num_fields); + temp_klass->SetFieldsPtr(fields); // 1. Create a static field 'interfaces' that holds the _declared_ interfaces implemented by // our proxy, so Class.getInterfaces doesn't return the flattened set. - ArtField& interfaces_sfield = sfields->At(0); + ArtField& interfaces_sfield = fields->At(0); interfaces_sfield.SetDexFieldIndex(0); interfaces_sfield.SetDeclaringClass(temp_klass.Get()); interfaces_sfield.SetAccessFlags(kAccStatic | kAccPublic | kAccFinal); // 2. Create a static field 'throws' that holds exceptions thrown by our methods. - ArtField& throws_sfield = sfields->At(1); + ArtField& throws_sfield = fields->At(1); throws_sfield.SetDexFieldIndex(1); throws_sfield.SetDeclaringClass(temp_klass.Get()); throws_sfield.SetAccessFlags(kAccStatic | kAccPublic | kAccFinal); @@ -5455,7 +5462,6 @@ ObjPtr<mirror::Class> ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRun // Consistency checks. if (kIsDebugBuild) { - CHECK(klass->GetIFieldsPtr() == nullptr); CheckProxyConstructor(klass->GetDirectMethod(0, image_pointer_size_)); for (size_t i = 0; i < num_virtual_methods; ++i) { @@ -5467,11 +5473,11 @@ ObjPtr<mirror::Class> ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRun Handle<mirror::String> decoded_name = hs2.NewHandle(soa.Decode<mirror::String>(name)); std::string interfaces_field_name(StringPrintf("java.lang.Class[] %s.interfaces", decoded_name->ToModifiedUtf8().c_str())); - CHECK_EQ(ArtField::PrettyField(klass->GetStaticField(0)), interfaces_field_name); + CHECK_EQ(ArtField::PrettyField(klass->GetField(0)), interfaces_field_name); std::string throws_field_name(StringPrintf("java.lang.Class[][] %s.throws", decoded_name->ToModifiedUtf8().c_str())); - CHECK_EQ(ArtField::PrettyField(klass->GetStaticField(1)), throws_field_name); + CHECK_EQ(ArtField::PrettyField(klass->GetField(1)), throws_field_name); CHECK_EQ(klass.Get()->GetProxyInterfaces(), soa.Decode<mirror::ObjectArray<mirror::Class>>(interfaces)); @@ -5576,7 +5582,7 @@ bool ClassLinker::CanWeInitializeClass(ObjPtr<mirror::Class> klass, return false; } // Check if there are encoded static values needing initialization. - if (klass->NumStaticFields() != 0) { + if (klass->HasStaticFields()) { const dex::ClassDef* dex_class_def = klass->GetClassDef(); DCHECK(dex_class_def != nullptr); if (dex_class_def->static_values_off_ != 0) { @@ -5804,8 +5810,7 @@ bool ClassLinker::InitializeClass(Thread* self, } } - const size_t num_static_fields = klass->NumStaticFields(); - if (num_static_fields > 0) { + if (klass->HasStaticFields()) { const dex::ClassDef* dex_class_def = klass->GetClassDef(); CHECK(dex_class_def != nullptr); StackHandleScope<2> hs(self); @@ -5814,8 +5819,11 @@ bool ClassLinker::InitializeClass(Thread* self, // Eagerly fill in static fields so that the we don't have to do as many expensive // Class::FindStaticField in ResolveField. - for (size_t i = 0; i < num_static_fields; ++i) { - ArtField* field = klass->GetStaticField(i); + for (size_t i = 0; i < klass->NumFields(); ++i) { + ArtField* field = klass->GetField(i); + if (!field->IsStatic()) { + continue; + } const uint32_t field_idx = field->GetDexFieldIndex(); ArtField* resolved_field = dex_cache->GetResolvedField(field_idx); if (resolved_field == nullptr) { @@ -6258,15 +6266,8 @@ bool ClassLinker::EnsureInitialized(Thread* self, void ClassLinker::FixupTemporaryDeclaringClass(ObjPtr<mirror::Class> temp_class, ObjPtr<mirror::Class> new_class) { - DCHECK_EQ(temp_class->NumInstanceFields(), 0u); - for (ArtField& field : new_class->GetIFields()) { - if (field.GetDeclaringClass() == temp_class) { - field.SetDeclaringClass(new_class); - } - } - - DCHECK_EQ(temp_class->NumStaticFields(), 0u); - for (ArtField& field : new_class->GetSFields()) { + DCHECK_EQ(temp_class->NumFields(), 0u); + for (ArtField& field : new_class->GetFields()) { if (field.GetDeclaringClass() == temp_class) { field.SetDeclaringClass(new_class); } @@ -6413,8 +6414,7 @@ bool ClassLinker::LinkClass(Thread* self, // may not see any references to the target space and clean the card for a class if another // class had the same array pointer. klass->SetMethodsPtrUnchecked(nullptr, 0, 0); - klass->SetSFieldsPtrUnchecked(nullptr); - klass->SetIFieldsPtrUnchecked(nullptr); + klass->SetFieldsPtrUnchecked(nullptr); if (UNLIKELY(h_new_class == nullptr)) { self->AssertPendingOOMException(); mirror::Class::SetStatus(klass, ClassStatus::kErrorUnresolved, self); @@ -9283,9 +9283,7 @@ bool ClassLinker::LinkFieldsHelper::LinkFields(ClassLinker* class_linker, bool is_static, size_t* class_size) { self->AllowThreadSuspension(); - const size_t num_fields = is_static ? klass->NumStaticFields() : klass->NumInstanceFields(); - LengthPrefixedArray<ArtField>* const fields = is_static ? klass->GetSFieldsPtr() : - klass->GetIFieldsPtr(); + LengthPrefixedArray<ArtField>* const fields = klass->GetFieldsPtr(); // Initialize field_offset MemberOffset field_offset(0); @@ -9301,7 +9299,8 @@ bool ClassLinker::LinkFieldsHelper::LinkFields(ClassLinker* class_linker, } } - CHECK_EQ(num_fields == 0, fields == nullptr) << klass->PrettyClass(); + size_t num_fields = + is_static ? klass->ComputeNumStaticFields() : klass->ComputeNumInstanceFields(); // we want a relatively stable order so that adding new fields // minimizes disruption of C++ version such as Class and Method. @@ -9341,8 +9340,11 @@ bool ClassLinker::LinkFieldsHelper::LinkFields(ClassLinker* class_linker, size_t num_reference_fields = 0; size_t primitive_fields_start = num_fields; DCHECK_LE(num_fields, 1u << 16); - for (size_t i = 0; i != num_fields; ++i) { + for (size_t i = 0; i != klass->NumFields(); ++i) { ArtField* field = &fields->At(i); + if (field->IsStatic() != is_static) { + continue; + } const char* descriptor = field->GetTypeDescriptor(); FieldTypeOrder field_type_order = FieldTypeOrderFromFirstDescriptorCharacter(descriptor[0]); uint16_t field_index = dchecked_integral_cast<uint16_t>(i); @@ -9491,8 +9493,8 @@ bool ClassLinker::LinkFieldsHelper::LinkFields(ClassLinker* class_linker, // We know there are no non-reference fields in the Reference classes, and we know // that 'referent' is alphabetically last, so this is easy... CHECK_EQ(num_reference_fields, num_fields) << klass->PrettyClass(); - CHECK_STREQ(fields->At(num_fields - 1).GetName(), "referent") - << klass->PrettyClass(); + CHECK_STREQ(fields->At(klass->NumFields() - 2).GetName(), "referent"); + CHECK_STREQ(fields->At(klass->NumFields() - 1).GetName(), "slowPathEnabled"); --num_reference_fields; } @@ -9550,8 +9552,11 @@ bool ClassLinker::LinkFieldsHelper::LinkFields(ClassLinker* class_linker, num_reference_fields * sizeof(mirror::HeapReference<mirror::Object>)); MemberOffset current_ref_offset = start_ref_offset; - for (size_t i = 0; i < num_fields; i++) { + for (size_t i = 0; i < klass->NumFields(); i++) { ArtField* field = &fields->At(i); + if (field->IsStatic() != is_static) { + continue; + } VLOG(class_linker) << "LinkFields: " << (is_static ? "static" : "instance") << " class=" << klass->PrettyClass() << " field=" << field->PrettyField() << " offset=" << field->GetOffsetDuringLinking(); @@ -10182,19 +10187,16 @@ ArtField* ClassLinker::FindResolvedField(ObjPtr<mirror::Class> klass, uint32_t field_idx, bool is_static) { DCHECK(dex_cache->GetClassLoader() == class_loader); - ArtField* resolved = is_static ? klass->FindStaticField(dex_cache, field_idx) - : klass->FindInstanceField(dex_cache, field_idx); - if (resolved != nullptr && + ArtField* resolved = klass->FindField(dex_cache, field_idx); + if (resolved == nullptr || + is_static != resolved->IsStatic() || hiddenapi::ShouldDenyAccessToMember(resolved, hiddenapi::AccessContext(class_loader, dex_cache), hiddenapi::AccessMethod::kLinking)) { - resolved = nullptr; - } - - if (resolved != nullptr) { - dex_cache->SetResolvedField(field_idx, resolved); + return nullptr; } + dex_cache->SetResolvedField(field_idx, resolved); return resolved; } @@ -10348,7 +10350,7 @@ ObjPtr<mirror::MethodHandle> ClassLinker::ResolveMethodHandleForField( ArtField* target_field = ResolveField(method_handle.field_or_method_idx_, referrer, is_static); if (LIKELY(target_field != nullptr)) { - DCHECK_EQ(is_static, target_field->IsStatic()); + DCHECK_EQ(is_static, target_field->IsStatic()) << target_field->PrettyField(); ObjPtr<mirror::Class> target_class = target_field->GetDeclaringClass(); ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass(); if (UNLIKELY(!referring_class->CanAccessMember(target_class, target_field->GetAccessFlags()))) { |