template<size_t kNumReferences> inline FixedSizeHandleScope<kNumReferences>::FixedSizeHandleScope(BaseHandleScope* link)
: HandleScope(link, kNumReferences) { if (kDebugLocking) {
Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
}
static_assert(kNumReferences >= 1, "FixedSizeHandleScope must contain at least 1 reference");
DCHECK_EQ(&storage_[0], GetReferences()); // TODO: Figure out how to use a compile assert. if (kIsDebugBuild) { // Fill storage with "DEAD HAndleSCope", mapping H->"4" and S->"5". for (size_t i = 0; i < kNumReferences; ++i) {
GetReferences()[i].Assign(reinterpret_cast32<mirror::Object*>(0xdead4a5c));
}
}
}
template <typename Visitor> inlinevoid HandleScope::VisitRoots(Visitor&& visitor) { for (size_t i = 0, size = Size(); i < size; ++i) { // GetReference returns a pointer to the stack reference within the handle scope. If this // needs to be updated, it will be done by the root visitor.
StackReference<mirror::Object>* ref = GetHandle<mirror::Object>(i).GetReference(); if constexpr (std::is_invocable_v<std::remove_reference_t<Visitor>,
StackReference<mirror::Object>*>) {
visitor(ref);
} else {
visitor.VisitRootIfNonNull(ref);
}
}
}
template <typename Visitor> inlinevoid HandleScope::VisitHandles(Visitor&& visitor) { for (size_t i = 0, size = Size(); i < size; ++i) {
Handle<mirror::Object> handle = GetHandle<mirror::Object>(i); if (handle != nullptr) { if constexpr (std::is_invocable_v<std::remove_reference_t<Visitor>, Handle<mirror::Object>>) {
visitor(handle);
} else {
visitor.Visit(handle);
}
}
}
}
// The current size of this handle scope. inline uint32_t BaseHandleScope::Size() const { return LIKELY(!IsVariableSized())
? AsHandleScope()->Size()
: AsVariableSized()->Size();
}
// The current capacity of this handle scope. inline uint32_t BaseHandleScope::Capacity() const { return LIKELY(!IsVariableSized())
? AsHandleScope()->Capacity()
: AsVariableSized()->Capacity();
}
inline VariableSizedHandleScope::~VariableSizedHandleScope() { if (kDebugLocking) {
Locks::mutator_lock_->AssertSharedHeld(self_);
}
BaseHandleScope* top_handle_scope = self_->PopHandleScope();
DCHECK_EQ(top_handle_scope, this); // Don't delete first_scope_ since it is not heap allocated. while (current_scope_ != &first_scope_) {
LocalScopeType* next = down_cast<LocalScopeType*>(current_scope_->GetLink()); delete current_scope_;
current_scope_ = next;
}
}
inline uint32_t VariableSizedHandleScope::Size() const { const LocalScopeType* cur = current_scope_;
DCHECK(cur != nullptr); // The linked list of local scopes starts from the latest which may not be fully filled.
uint32_t sum = cur->Size();
cur = down_cast<const LocalScopeType*>(cur->GetLink()); while (cur != nullptr) { // All other local scopes are fully filled.
DCHECK_EQ(cur->Size(), kNumReferencesPerScope);
sum += kNumReferencesPerScope;
cur = down_cast<const LocalScopeType*>(cur->GetLink());
} return sum;
}
inline uint32_t VariableSizedHandleScope::Capacity() const {
uint32_t sum = 0; const LocalScopeType* cur = current_scope_; while (cur != nullptr) {
DCHECK_EQ(cur->Capacity(), kNumReferencesPerScope);
sum += kNumReferencesPerScope;
cur = down_cast<const LocalScopeType*>(cur->GetLink());
} return sum;
}
inlinebool VariableSizedHandleScope::Contains(StackReference<mirror::Object>* handle_scope_entry) const { const LocalScopeType* cur = current_scope_; while (cur != nullptr) { if (cur->Contains(handle_scope_entry)) { returntrue;
}
cur = down_cast<const LocalScopeType*>(cur->GetLink());
} returnfalse;
}
template<class T>
Handle<T> VariableSizedHandleScope::GetHandle(size_t i) { // Handle the most common path efficiently. if (i < kNumReferencesPerScope) { return first_scope_.GetHandle<T>(i);
}
uint32_t size = Size();
DCHECK_GT(size, kNumReferencesPerScope);
DCHECK_LT(i, size);
LocalScopeType* cur = current_scope_;
DCHECK(cur != &first_scope_); // The linked list of local scopes starts from the latest which may not be fully filled.
uint32_t cur_start = size - cur->Size();
DCHECK_EQ(cur_start % kNumReferencesPerScope, 0u); // All other local scopes are fully filled. while (i < cur_start) {
cur = down_cast<LocalScopeType*>(cur->GetLink());
DCHECK(cur != nullptr);
DCHECK_EQ(cur->Size(), kNumReferencesPerScope);
cur_start -= kNumReferencesPerScope;
} return cur->GetHandle<T>(i - cur_start);
}
template <typename Visitor> inlinevoid VariableSizedHandleScope::VisitRoots(Visitor&& visitor) {
LocalScopeType* cur = current_scope_; while (cur != nullptr) {
cur->VisitRoots(visitor);
cur = down_cast<LocalScopeType*>(cur->GetLink());
}
}
template <typename Visitor> inlinevoid VariableSizedHandleScope::VisitHandles(Visitor&& visitor) {
LocalScopeType* cur = current_scope_; while (cur != nullptr) {
cur->VisitHandles(visitor);
cur = down_cast<LocalScopeType*>(cur->GetLink());
}
}
} // namespace art
#endif// ART_RUNTIME_HANDLE_SCOPE_INL_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.2 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.