xref: /aosp_15_r20/art/runtime/handle_scope.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_HANDLE_SCOPE_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_HANDLE_SCOPE_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <stack>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker #include "base/locks.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
27*795d594fSAndroid Build Coastguard Worker #include "stack_reference.h"
28*795d594fSAndroid Build Coastguard Worker 
29*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker template<class T> class Handle;
32*795d594fSAndroid Build Coastguard Worker class HandleScope;
33*795d594fSAndroid Build Coastguard Worker template<class T> class HandleWrapper;
34*795d594fSAndroid Build Coastguard Worker template<class T> class HandleWrapperObjPtr;
35*795d594fSAndroid Build Coastguard Worker template<class T> class MutableHandle;
36*795d594fSAndroid Build Coastguard Worker template<class MirrorType> class ObjPtr;
37*795d594fSAndroid Build Coastguard Worker class Thread;
38*795d594fSAndroid Build Coastguard Worker class VariableSizedHandleScope;
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker namespace mirror {
41*795d594fSAndroid Build Coastguard Worker class Object;
42*795d594fSAndroid Build Coastguard Worker }  // namespace mirror
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker // Basic handle scope, tracked by a list. May be variable sized.
45*795d594fSAndroid Build Coastguard Worker class PACKED(4) BaseHandleScope {
46*795d594fSAndroid Build Coastguard Worker  public:
IsVariableSized()47*795d594fSAndroid Build Coastguard Worker   bool IsVariableSized() const {
48*795d594fSAndroid Build Coastguard Worker     return capacity_ == kNumReferencesVariableSized;
49*795d594fSAndroid Build Coastguard Worker   }
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker   // The current size of this handle scope.
52*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE uint32_t Size() const;
53*795d594fSAndroid Build Coastguard Worker 
54*795d594fSAndroid Build Coastguard Worker   // The current capacity of this handle scope.
55*795d594fSAndroid Build Coastguard Worker   // It can change (increase) only for a `VariableSizedHandleScope`.
56*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE uint32_t Capacity() const;
57*795d594fSAndroid Build Coastguard Worker 
58*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool Contains(StackReference<mirror::Object>* handle_scope_entry) const;
59*795d594fSAndroid Build Coastguard Worker 
60*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
61*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitRoots(Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_);
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
64*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitHandles(Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_);
65*795d594fSAndroid Build Coastguard Worker 
66*795d594fSAndroid Build Coastguard Worker   // Link to previous BaseHandleScope or null.
GetLink()67*795d594fSAndroid Build Coastguard Worker   BaseHandleScope* GetLink() const {
68*795d594fSAndroid Build Coastguard Worker     return link_;
69*795d594fSAndroid Build Coastguard Worker   }
70*795d594fSAndroid Build Coastguard Worker 
71*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE VariableSizedHandleScope* AsVariableSized();
72*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE HandleScope* AsHandleScope();
73*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE const VariableSizedHandleScope* AsVariableSized() const;
74*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE const HandleScope* AsHandleScope() const;
75*795d594fSAndroid Build Coastguard Worker 
76*795d594fSAndroid Build Coastguard Worker  protected:
BaseHandleScope(BaseHandleScope * link,uint32_t capacity)77*795d594fSAndroid Build Coastguard Worker   BaseHandleScope(BaseHandleScope* link, uint32_t capacity)
78*795d594fSAndroid Build Coastguard Worker       : link_(link),
79*795d594fSAndroid Build Coastguard Worker         capacity_(capacity) {}
80*795d594fSAndroid Build Coastguard Worker 
81*795d594fSAndroid Build Coastguard Worker   // Variable sized constructor.
BaseHandleScope(BaseHandleScope * link)82*795d594fSAndroid Build Coastguard Worker   explicit BaseHandleScope(BaseHandleScope* link)
83*795d594fSAndroid Build Coastguard Worker       : link_(link),
84*795d594fSAndroid Build Coastguard Worker         capacity_(kNumReferencesVariableSized) {}
85*795d594fSAndroid Build Coastguard Worker 
86*795d594fSAndroid Build Coastguard Worker   static constexpr int32_t kNumReferencesVariableSized = -1;
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker   // Link-list of handle scopes. The root is held by a Thread.
89*795d594fSAndroid Build Coastguard Worker   BaseHandleScope* const link_;
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker   // Number of handlerized references. -1 for variable sized handle scopes.
92*795d594fSAndroid Build Coastguard Worker   const int32_t capacity_;
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker  private:
95*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(BaseHandleScope);
96*795d594fSAndroid Build Coastguard Worker };
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker // HandleScopes are scoped objects containing a number of Handles. They are used to allocate
99*795d594fSAndroid Build Coastguard Worker // handles, for these handles (and the objects contained within them) to be visible/roots for the
100*795d594fSAndroid Build Coastguard Worker // GC. It is most common to stack allocate HandleScopes using StackHandleScope.
101*795d594fSAndroid Build Coastguard Worker class PACKED(4) HandleScope : public BaseHandleScope {
102*795d594fSAndroid Build Coastguard Worker  public:
~HandleScope()103*795d594fSAndroid Build Coastguard Worker   ~HandleScope() {}
104*795d594fSAndroid Build Coastguard Worker 
105*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ObjPtr<mirror::Object> GetReference(size_t i) const
106*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
107*795d594fSAndroid Build Coastguard Worker 
108*795d594fSAndroid Build Coastguard Worker   template<class T>
109*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE Handle<T> GetHandle(size_t i) REQUIRES_SHARED(Locks::mutator_lock_);
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker   template<class T>
112*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE MutableHandle<T> GetMutableHandle(size_t i) REQUIRES_SHARED(Locks::mutator_lock_);
113*795d594fSAndroid Build Coastguard Worker 
114*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetReference(size_t i, ObjPtr<mirror::Object> object)
115*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
116*795d594fSAndroid Build Coastguard Worker 
117*795d594fSAndroid Build Coastguard Worker   template<class T>
118*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE MutableHandle<T> NewHandle(T* object) REQUIRES_SHARED(Locks::mutator_lock_);
119*795d594fSAndroid Build Coastguard Worker 
120*795d594fSAndroid Build Coastguard Worker   template<class T>
121*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE HandleWrapper<T> NewHandleWrapper(T** object)
122*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker   template<class T>
125*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE HandleWrapperObjPtr<T> NewHandleWrapper(ObjPtr<T>* object)
126*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker   template<class MirrorType>
129*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE MutableHandle<MirrorType> NewHandle(ObjPtr<MirrorType> object)
130*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_);
131*795d594fSAndroid Build Coastguard Worker 
132*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool Contains(StackReference<mirror::Object>* handle_scope_entry) const;
133*795d594fSAndroid Build Coastguard Worker 
134*795d594fSAndroid Build Coastguard Worker   // Offset of link within HandleScope, used by generated code.
LinkOffset(PointerSize pointer_size)135*795d594fSAndroid Build Coastguard Worker   static constexpr size_t LinkOffset([[maybe_unused]] PointerSize pointer_size) { return 0; }
136*795d594fSAndroid Build Coastguard Worker 
137*795d594fSAndroid Build Coastguard Worker   // Offset of length within handle scope, used by generated code.
CapacityOffset(PointerSize pointer_size)138*795d594fSAndroid Build Coastguard Worker   static constexpr size_t CapacityOffset(PointerSize pointer_size) {
139*795d594fSAndroid Build Coastguard Worker     return static_cast<size_t>(pointer_size);
140*795d594fSAndroid Build Coastguard Worker   }
141*795d594fSAndroid Build Coastguard Worker 
142*795d594fSAndroid Build Coastguard Worker   // Offset of link within handle scope, used by generated code.
ReferencesOffset(PointerSize pointer_size)143*795d594fSAndroid Build Coastguard Worker   static constexpr size_t ReferencesOffset(PointerSize pointer_size) {
144*795d594fSAndroid Build Coastguard Worker     return CapacityOffset(pointer_size) + sizeof(capacity_) + sizeof(size_);
145*795d594fSAndroid Build Coastguard Worker   }
146*795d594fSAndroid Build Coastguard Worker 
147*795d594fSAndroid Build Coastguard Worker   // The current size of this handle scope.
Size()148*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE uint32_t Size() const {
149*795d594fSAndroid Build Coastguard Worker     return size_;
150*795d594fSAndroid Build Coastguard Worker   }
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker   // The capacity of this handle scope, immutable.
Capacity()153*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE uint32_t Capacity() const {
154*795d594fSAndroid Build Coastguard Worker     DCHECK_GT(capacity_, 0);
155*795d594fSAndroid Build Coastguard Worker     return static_cast<uint32_t>(capacity_);
156*795d594fSAndroid Build Coastguard Worker   }
157*795d594fSAndroid Build Coastguard Worker 
158*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
159*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitRoots(Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_);
160*795d594fSAndroid Build Coastguard Worker 
161*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
162*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitHandles(Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_);
163*795d594fSAndroid Build Coastguard Worker 
164*795d594fSAndroid Build Coastguard Worker  protected:
165*795d594fSAndroid Build Coastguard Worker   // Return backing storage used for references.
GetReferences()166*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE StackReference<mirror::Object>* GetReferences() const {
167*795d594fSAndroid Build Coastguard Worker     uintptr_t address = reinterpret_cast<uintptr_t>(this) + ReferencesOffset(kRuntimePointerSize);
168*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<StackReference<mirror::Object>*>(address);
169*795d594fSAndroid Build Coastguard Worker   }
170*795d594fSAndroid Build Coastguard Worker 
HandleScope(size_t capacity)171*795d594fSAndroid Build Coastguard Worker   explicit HandleScope(size_t capacity) : HandleScope(nullptr, capacity) {}
172*795d594fSAndroid Build Coastguard Worker 
HandleScope(BaseHandleScope * link,uint32_t capacity)173*795d594fSAndroid Build Coastguard Worker   HandleScope(BaseHandleScope* link, uint32_t capacity)
174*795d594fSAndroid Build Coastguard Worker       : BaseHandleScope(link, capacity) {
175*795d594fSAndroid Build Coastguard Worker     // Handle scope should be created only if we have a code path that stores something in it.
176*795d594fSAndroid Build Coastguard Worker     // We may not take that code path and the handle scope may remain empty.
177*795d594fSAndroid Build Coastguard Worker     DCHECK_NE(capacity, 0u);
178*795d594fSAndroid Build Coastguard Worker   }
179*795d594fSAndroid Build Coastguard Worker 
180*795d594fSAndroid Build Coastguard Worker   // Position new handles will be created.
181*795d594fSAndroid Build Coastguard Worker   uint32_t size_ = 0;
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker   // Storage for references is in derived classes.
184*795d594fSAndroid Build Coastguard Worker   // StackReference<mirror::Object> references_[capacity_]
185*795d594fSAndroid Build Coastguard Worker 
186*795d594fSAndroid Build Coastguard Worker  private:
187*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(HandleScope);
188*795d594fSAndroid Build Coastguard Worker };
189*795d594fSAndroid Build Coastguard Worker 
190*795d594fSAndroid Build Coastguard Worker // Fixed size handle scope that is not necessarily linked in the thread.
191*795d594fSAndroid Build Coastguard Worker template<size_t kNumReferences>
192*795d594fSAndroid Build Coastguard Worker class PACKED(4) FixedSizeHandleScope : public HandleScope {
193*795d594fSAndroid Build Coastguard Worker  private:
194*795d594fSAndroid Build Coastguard Worker   explicit ALWAYS_INLINE FixedSizeHandleScope(BaseHandleScope* link)
195*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
~FixedSizeHandleScope()196*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ~FixedSizeHandleScope() REQUIRES_SHARED(Locks::mutator_lock_) {}
197*795d594fSAndroid Build Coastguard Worker 
198*795d594fSAndroid Build Coastguard Worker   // Reference storage.
199*795d594fSAndroid Build Coastguard Worker   StackReference<mirror::Object> storage_[kNumReferences];
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker   template<size_t kNumRefs> friend class StackHandleScope;
202*795d594fSAndroid Build Coastguard Worker   friend class VariableSizedHandleScope;
203*795d594fSAndroid Build Coastguard Worker };
204*795d594fSAndroid Build Coastguard Worker 
205*795d594fSAndroid Build Coastguard Worker // Scoped handle storage of a fixed size that is stack allocated.
206*795d594fSAndroid Build Coastguard Worker template<size_t kNumReferences>
207*795d594fSAndroid Build Coastguard Worker class PACKED(4) StackHandleScope final : public FixedSizeHandleScope<kNumReferences> {
208*795d594fSAndroid Build Coastguard Worker  public:
209*795d594fSAndroid Build Coastguard Worker   explicit ALWAYS_INLINE StackHandleScope(Thread* self)
210*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
211*795d594fSAndroid Build Coastguard Worker 
212*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ~StackHandleScope() REQUIRES_SHARED(Locks::mutator_lock_);
213*795d594fSAndroid Build Coastguard Worker 
Self()214*795d594fSAndroid Build Coastguard Worker   Thread* Self() const {
215*795d594fSAndroid Build Coastguard Worker     return self_;
216*795d594fSAndroid Build Coastguard Worker   }
217*795d594fSAndroid Build Coastguard Worker 
218*795d594fSAndroid Build Coastguard Worker  private:
219*795d594fSAndroid Build Coastguard Worker   // The thread that the stack handle scope is a linked list upon. The stack handle scope will
220*795d594fSAndroid Build Coastguard Worker   // push and pop itself from this thread.
221*795d594fSAndroid Build Coastguard Worker   Thread* const self_;
222*795d594fSAndroid Build Coastguard Worker };
223*795d594fSAndroid Build Coastguard Worker 
224*795d594fSAndroid Build Coastguard Worker // Utility class to manage a variable sized handle scope by having a list of fixed size handle
225*795d594fSAndroid Build Coastguard Worker // scopes.
226*795d594fSAndroid Build Coastguard Worker // Calls to NewHandle will create a new handle inside the current FixedSizeHandleScope.
227*795d594fSAndroid Build Coastguard Worker // When the current handle scope becomes full a new one is created and put at the front of the
228*795d594fSAndroid Build Coastguard Worker // list.
229*795d594fSAndroid Build Coastguard Worker class VariableSizedHandleScope : public BaseHandleScope {
230*795d594fSAndroid Build Coastguard Worker  public:
231*795d594fSAndroid Build Coastguard Worker   explicit VariableSizedHandleScope(Thread* const self) REQUIRES_SHARED(Locks::mutator_lock_);
232*795d594fSAndroid Build Coastguard Worker   ~VariableSizedHandleScope() REQUIRES_SHARED(Locks::mutator_lock_);
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker   template<class T>
235*795d594fSAndroid Build Coastguard Worker   MutableHandle<T> NewHandle(T* object) REQUIRES_SHARED(Locks::mutator_lock_);
236*795d594fSAndroid Build Coastguard Worker 
237*795d594fSAndroid Build Coastguard Worker   template<class MirrorType>
238*795d594fSAndroid Build Coastguard Worker   MutableHandle<MirrorType> NewHandle(ObjPtr<MirrorType> ptr)
239*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
240*795d594fSAndroid Build Coastguard Worker 
241*795d594fSAndroid Build Coastguard Worker   // The current size of this handle scope.
242*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE uint32_t Size() const;
243*795d594fSAndroid Build Coastguard Worker 
244*795d594fSAndroid Build Coastguard Worker   // The current capacity of this handle scope.
245*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE uint32_t Capacity() const;
246*795d594fSAndroid Build Coastguard Worker 
247*795d594fSAndroid Build Coastguard Worker   // Retrieve a `Handle<>` based on the slot index (in handle creation order).
248*795d594fSAndroid Build Coastguard Worker   // Note: This is linear in the size of the scope, so it should be used carefully.
249*795d594fSAndroid Build Coastguard Worker   template<class T>
250*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE Handle<T> GetHandle(size_t i) REQUIRES_SHARED(Locks::mutator_lock_);
251*795d594fSAndroid Build Coastguard Worker 
252*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool Contains(StackReference<mirror::Object>* handle_scope_entry) const;
253*795d594fSAndroid Build Coastguard Worker 
254*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
255*795d594fSAndroid Build Coastguard Worker   void VisitRoots(Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_);
256*795d594fSAndroid Build Coastguard Worker 
257*795d594fSAndroid Build Coastguard Worker   template <typename Visitor>
258*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void VisitHandles(Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_);
259*795d594fSAndroid Build Coastguard Worker 
260*795d594fSAndroid Build Coastguard Worker  private:
261*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kLocalScopeSize = 64u;
262*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kSizeOfReferencesPerScope =
263*795d594fSAndroid Build Coastguard Worker       kLocalScopeSize
264*795d594fSAndroid Build Coastguard Worker           - /* BaseHandleScope::link_ */ sizeof(BaseHandleScope*)
265*795d594fSAndroid Build Coastguard Worker           - /* BaseHandleScope::capacity_ */ sizeof(int32_t)
266*795d594fSAndroid Build Coastguard Worker           - /* HandleScope<>::size_ */ sizeof(uint32_t);
267*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kNumReferencesPerScope =
268*795d594fSAndroid Build Coastguard Worker       kSizeOfReferencesPerScope / sizeof(StackReference<mirror::Object>);
269*795d594fSAndroid Build Coastguard Worker 
270*795d594fSAndroid Build Coastguard Worker   Thread* const self_;
271*795d594fSAndroid Build Coastguard Worker 
272*795d594fSAndroid Build Coastguard Worker   // Linked list of fixed size handle scopes.
273*795d594fSAndroid Build Coastguard Worker   using LocalScopeType = FixedSizeHandleScope<kNumReferencesPerScope>;
274*795d594fSAndroid Build Coastguard Worker   static_assert(sizeof(LocalScopeType) == kLocalScopeSize, "Unexpected size of LocalScopeType");
275*795d594fSAndroid Build Coastguard Worker   LocalScopeType* current_scope_;
276*795d594fSAndroid Build Coastguard Worker   LocalScopeType first_scope_;
277*795d594fSAndroid Build Coastguard Worker 
278*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(VariableSizedHandleScope);
279*795d594fSAndroid Build Coastguard Worker };
280*795d594fSAndroid Build Coastguard Worker 
281*795d594fSAndroid Build Coastguard Worker }  // namespace art
282*795d594fSAndroid Build Coastguard Worker 
283*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_HANDLE_SCOPE_H_
284