template<typename T> staticvoid InitializeArray(T*) { // Nothing to do.
}
template<typename T>
T* DexCache::AllocArray(MemberOffset obj_offset, size_t num, LinearAllocKind kind, boolstartup) {
Thread* self = Thread::Current();
mirror::DexCache* dex_cache = this; if (gUseReadBarrier && self->GetIsGcMarking()) { // Several code paths use DexCache without read-barrier for performance. // We have to check the "to-space" object here to avoid allocating twice.
dex_cache = reinterpret_cast<DexCache*>(ReadBarrier::Mark(this));
} // DON'T USE 'this' from now on.
Runtime* runtime = Runtime::Current(); // Note: in the 1002-notify-startup test, the startup linear alloc can become null // concurrently, even if the runtime is marked at startup. Therefore we should only // fetch it once here.
LinearAlloc* startup_linear_alloc = runtime->GetStartupLinearAlloc();
LinearAlloc* alloc = (startup && startup_linear_alloc != nullptr)
? startup_linear_alloc
: runtime->GetClassLinker()->GetOrCreateAllocatorForClassLoader(GetClassLoader());
MutexLock mu(self, *Locks::dex_cache_lock_); // Avoid allocation by multiple threads.
T* array = dex_cache->GetFieldPtr64<T*>(obj_offset); if (array != nullptr) {
DCHECK(alloc->Contains(array)); return array; // Other thread just allocated the array.
}
array = reinterpret_cast<T*>(alloc->AllocAlign16(self, RoundUp(num * sizeof(T), 16), kind));
InitializeArray(array); // Ensure other threads see the array initialized.
dex_cache->SetField64Volatile<false, false>(obj_offset, reinterpret_cast64<uint64_t>(array)); return array;
}
inlinevoid DexCache::SetResolvedString(dex::StringIndex string_idx, ObjPtr<String> resolved) {
DCHECK(resolved != nullptr);
SetStringsEntry(string_idx.index_, resolved.Ptr());
Runtime* const runtime = Runtime::Current(); if (UNLIKELY(runtime->IsActiveTransaction())) {
DCHECK(runtime->IsAotCompiler());
runtime->GetClassLinker()->RecordResolveString(this, string_idx);
} // TODO: Fine-grained marking, so that we don't need to go through all arrays in full.
WriteBarrier::ForEveryFieldWrite(this);
}
Runtime* const runtime = Runtime::Current(); if (UNLIKELY(runtime->IsActiveTransaction())) {
DCHECK(runtime->IsAotCompiler());
runtime->GetClassLinker()->RecordResolveMethodType(this, proto_idx);
} // TODO: Fine-grained marking, so that we don't need to go through all arrays in full.
WriteBarrier::ForEveryFieldWrite(this);
}
// The first assignment for a given call site wins. if (target->CompareAndSetStrongSequentiallyConsistent(null_call_site, candidate)) { // TODO: Fine-grained marking, so that we don't need to go through all arrays in full.
WriteBarrier::ForEveryFieldWrite(this); return call_site;
} else { return target->load(std::memory_order_relaxed).Read();
}
}
template <ReadBarrierOption kReadBarrierOption, typename Visitor, typename T> inlinevoid VisitDexCachePairs(T* array,
size_t num_pairs, const Visitor& visitor)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_) {
DCHECK_NE(array, nullptr); for (size_t i = 0; i < num_pairs; ++i) { auto source = array->GetPair(i); // NOTE: We need the "template" keyword here to avoid a compilation // failure. GcRoot<T> is a template argument-dependent type and we need to // tell the compiler to treat "Read" as a template rather than a field or // function. Otherwise, on encountering the "<" token, the compiler would // treat "Read" as a field. autoconst before = source.object.template Read<kReadBarrierOption>();
visitor.VisitRootIfNonNull(source.object.AddressWithoutBarrier()); if (source.object.template Read<kReadBarrierOption>() != before) {
array->SetPair(i, source);
}
}
}
GcRootArray<mirror::CallSite>* resolved_call_sites = GetResolvedCallSites<kVerifyFlags>(); if (should_visit(resolved_call_sites)) {
size_t num_call_sites = NumResolvedCallSites<kVerifyFlags>(); for (size_t i = 0; i != num_call_sites; ++i) {
visitor.VisitRootIfNonNull(resolved_call_sites->GetGcRootAddress(i)->AddressWithoutBarrier());
}
}
// Dex cache arrays can be reset and cleared during app startup. Assert we do not get // suspended to ensure the arrays are not deallocated.
ScopedAssertNoThreadSuspension soants("dex caches");
GcRootArray<mirror::Class>* resolved_types_arr = GetResolvedTypesArray<kVerifyFlags>(); if (should_visit(resolved_types_arr)) {
size_t num_resolved_types = NumResolvedTypesArray<kVerifyFlags>(); for (size_t i = 0; i != num_resolved_types; ++i) {
visitor.VisitRootIfNonNull(resolved_types_arr->GetGcRootAddress(i)->AddressWithoutBarrier());
}
}
GcRootArray<mirror::String>* resolved_strings = GetStringsArray<kVerifyFlags>(); if (should_visit(resolved_strings)) {
size_t num_resolved_strings = NumStringsArray<kVerifyFlags>(); for (size_t i = 0; i != num_resolved_strings; ++i) {
visitor.VisitRootIfNonNull(resolved_strings->GetGcRootAddress(i)->AddressWithoutBarrier());
}
}
GcRootArray<mirror::MethodType>* resolved_method_types_arr =
GetResolvedMethodTypesArray<kVerifyFlags>(); if (should_visit(resolved_method_types_arr)) {
size_t num_resolved_method_types = NumResolvedMethodTypesArray<kVerifyFlags>(); for (size_t i = 0; i != num_resolved_method_types; ++i) {
visitor.VisitRootIfNonNull(
resolved_method_types_arr->GetGcRootAddress(i)->AddressWithoutBarrier());
}
}
}
template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> inline ObjPtr<String> DexCache::GetLocation(bool allow_location_mismatch) {
ObjPtr<String> location = GetFieldObject<String, kVerifyFlags, kReadBarrierOption>(
OFFSET_OF_OBJECT_MEMBER(DexCache, location_)); // At runtime, if the DexCache is from an app image or dynamically created, then its location must // match the DexFile location. // TODO(jiakaiz): Remove the AOT compiler and boot classpath checks? if (kIsDebugBuild && !allow_location_mismatch && !Runtime::Current()->IsAotCompiler() &&
GetDexFile() != nullptr && !ClassLinker::IsBootClassLoader(GetClassLoader())) {
DCHECK_EQ(location->ToModifiedUtf8(), GetDexFile()->GetLocation());
} return location;
}
} // namespace mirror
} // namespace art
#endif// ART_RUNTIME_MIRROR_DEX_CACHE_INL_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.