diff options
author | 2023-11-09 18:07:24 +0100 | |
---|---|---|
committer | 2023-11-20 10:38:07 +0000 | |
commit | 4f2fcccce50f229cb2b00cc07c040473a59c120b (patch) | |
tree | 2f5a6d61b796b95ea63e60bea47cbf6d9be2c482 /runtime/handle_scope-inl.h | |
parent | 58310a99bcda9a45bc1e07f8d36f4c847f345457 (diff) |
Do not create `MethodType` during early init...
... when interpreting `VarHandle` invoke-polymorphic.
Use `VariableSizedHandleScope` as a raw method type that can
be converted to the managed `MethodType` when desires but
can also be used directly without the conversion. Add helper
templates that facilitate using either the raw method type
or the managed `MethodType` easily by templated code.
Change `VarHandleInvokeAccessorWithConversions()` to avoid
allocating the `MethodType` (avoid unnecessary work).
Change `VarHandle` invokes in the interpreter to avoid
allocating the `MethodType` when the `ThreadLocalRandom`
is not initialized. This can avoid circular initialization
when we reland
https://android-review.googlesource.com/2769639 .
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 297147201
Change-Id: I6a9372543a547366b28e5bf49d15d6140a75f770
Diffstat (limited to 'runtime/handle_scope-inl.h')
-rw-r--r-- | runtime/handle_scope-inl.h | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/runtime/handle_scope-inl.h b/runtime/handle_scope-inl.h index 1874237174..e620e92e1f 100644 --- a/runtime/handle_scope-inl.h +++ b/runtime/handle_scope-inl.h @@ -19,6 +19,7 @@ #include "handle_scope.h" +#include "base/casts.h" #include "base/mutex.h" #include "handle.h" #include "handle_wrapper.h" @@ -246,12 +247,12 @@ inline uint32_t VariableSizedHandleScope::Size() const { 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 = reinterpret_cast<const LocalScopeType*>(cur->GetLink()); + 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 = reinterpret_cast<const LocalScopeType*>(cur->GetLink()); + cur = down_cast<const LocalScopeType*>(cur->GetLink()); } return sum; } @@ -262,7 +263,7 @@ inline uint32_t VariableSizedHandleScope::Capacity() const { while (cur != nullptr) { DCHECK_EQ(cur->Capacity(), kNumReferencesPerScope); sum += kNumReferencesPerScope; - cur = reinterpret_cast<const LocalScopeType*>(cur->GetLink()); + cur = down_cast<const LocalScopeType*>(cur->GetLink()); } return sum; } @@ -274,17 +275,41 @@ inline bool VariableSizedHandleScope::Contains(StackReference<mirror::Object>* h if (cur->Contains(handle_scope_entry)) { return true; } - cur = reinterpret_cast<const LocalScopeType*>(cur->GetLink()); + cur = down_cast<const LocalScopeType*>(cur->GetLink()); } return false; } +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> inline void VariableSizedHandleScope::VisitRoots(Visitor& visitor) { LocalScopeType* cur = current_scope_; while (cur != nullptr) { cur->VisitRoots(visitor); - cur = reinterpret_cast<LocalScopeType*>(cur->GetLink()); + cur = down_cast<LocalScopeType*>(cur->GetLink()); } } @@ -293,7 +318,7 @@ inline void VariableSizedHandleScope::VisitHandles(Visitor& visitor) { LocalScopeType* cur = current_scope_; while (cur != nullptr) { cur->VisitHandles(visitor); - cur = reinterpret_cast<LocalScopeType*>(cur->GetLink()); + cur = down_cast<LocalScopeType*>(cur->GetLink()); } } |