blob: 6d8a05dcd285d50ab1e8ff5dec5cf00655aea70e [file] [log] [blame]
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_HANDLE_SCOPE_INL_H_
18#define ART_RUNTIME_HANDLE_SCOPE_INL_H_
19
Ian Rogers22d5e732014-07-15 22:23:51 -070020#include "handle_scope.h"
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070021
Mathieu Chartiered150002015-08-28 11:16:54 -070022#include "base/mutex.h"
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070023#include "handle.h"
Andreas Gampea1ffdba2019-01-04 16:08:51 -080024#include "handle_wrapper.h"
Vladimir Markoabedfca2019-05-23 14:07:47 +010025#include "mirror/object_reference-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070026#include "obj_ptr-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070027#include "thread-current-inl.h"
Andreas Gampe90b936d2017-01-31 08:58:55 -080028#include "verify_object.h"
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070029
30namespace art {
31
32template<size_t kNumReferences>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070033inline FixedSizeHandleScope<kNumReferences>::FixedSizeHandleScope(BaseHandleScope* link,
Vladimir Markoabedfca2019-05-23 14:07:47 +010034 ObjPtr<mirror::Object> fill_value)
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070035 : HandleScope(link, kNumReferences) {
Mathieu Chartiered150002015-08-28 11:16:54 -070036 if (kDebugLocking) {
37 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
38 }
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070039 static_assert(kNumReferences >= 1, "FixedSizeHandleScope must contain at least 1 reference");
40 DCHECK_EQ(&storage_[0], GetReferences()); // TODO: Figure out how to use a compile assert.
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070041 for (size_t i = 0; i < kNumReferences; ++i) {
Mathieu Chartier2d2621a2014-10-23 16:48:06 -070042 SetReference(i, fill_value);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070043 }
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070044}
45
46template<size_t kNumReferences>
Vladimir Markoabedfca2019-05-23 14:07:47 +010047inline StackHandleScope<kNumReferences>::StackHandleScope(Thread* self,
48 ObjPtr<mirror::Object> fill_value)
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070049 : FixedSizeHandleScope<kNumReferences>(self->GetTopHandleScope(), fill_value),
50 self_(self) {
51 DCHECK_EQ(self, Thread::Current());
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070052 self_->PushHandleScope(this);
53}
54
55template<size_t kNumReferences>
Mathieu Chartier421c5372014-05-14 14:11:40 -070056inline StackHandleScope<kNumReferences>::~StackHandleScope() {
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070057 BaseHandleScope* top_handle_scope = self_->PopHandleScope();
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070058 DCHECK_EQ(top_handle_scope, this);
Mathieu Chartiered150002015-08-28 11:16:54 -070059 if (kDebugLocking) {
60 Locks::mutator_lock_->AssertSharedHeld(self_);
61 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070062}
63
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080064inline size_t HandleScope::SizeOf(uint32_t num_references) {
65 size_t header_size = sizeof(HandleScope);
66 size_t data_size = sizeof(StackReference<mirror::Object>) * num_references;
67 return header_size + data_size;
68}
69
Andreas Gampe542451c2016-07-26 09:02:02 -070070inline size_t HandleScope::SizeOf(PointerSize pointer_size, uint32_t num_references) {
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080071 // Assume that the layout is packed.
Andreas Gampe542451c2016-07-26 09:02:02 -070072 size_t header_size = ReferencesOffset(pointer_size);
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080073 size_t data_size = sizeof(StackReference<mirror::Object>) * num_references;
74 return header_size + data_size;
75}
76
Vladimir Markoabedfca2019-05-23 14:07:47 +010077inline ObjPtr<mirror::Object> HandleScope::GetReference(size_t i) const {
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070078 DCHECK_LT(i, NumberOfReferences());
Mathieu Chartiered150002015-08-28 11:16:54 -070079 if (kDebugLocking) {
80 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
81 }
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080082 return GetReferences()[i].AsMirrorPtr();
83}
84
85inline Handle<mirror::Object> HandleScope::GetHandle(size_t i) {
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070086 DCHECK_LT(i, NumberOfReferences());
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080087 return Handle<mirror::Object>(&GetReferences()[i]);
88}
89
90inline MutableHandle<mirror::Object> HandleScope::GetMutableHandle(size_t i) {
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070091 DCHECK_LT(i, NumberOfReferences());
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080092 return MutableHandle<mirror::Object>(&GetReferences()[i]);
93}
94
Vladimir Markoabedfca2019-05-23 14:07:47 +010095inline void HandleScope::SetReference(size_t i, ObjPtr<mirror::Object> object) {
Mathieu Chartiered150002015-08-28 11:16:54 -070096 if (kDebugLocking) {
97 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
98 }
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070099 DCHECK_LT(i, NumberOfReferences());
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800100 GetReferences()[i].Assign(object);
101}
102
103inline bool HandleScope::Contains(StackReference<mirror::Object>* handle_scope_entry) const {
104 // A HandleScope should always contain something. One created by the
105 // jni_compiler should have a jobject/jclass as a native method is
106 // passed in a this pointer or a class
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700107 DCHECK_GT(NumberOfReferences(), 0U);
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800108 return &GetReferences()[0] <= handle_scope_entry &&
109 handle_scope_entry <= &GetReferences()[number_of_references_ - 1];
110}
111
Andreas Gampea1ffdba2019-01-04 16:08:51 -0800112template <typename Visitor>
113inline void HandleScope::VisitRoots(Visitor& visitor) {
114 for (size_t i = 0, count = NumberOfReferences(); i < count; ++i) {
115 // GetReference returns a pointer to the stack reference within the handle scope. If this
116 // needs to be updated, it will be done by the root visitor.
117 visitor.VisitRootIfNonNull(GetHandle(i).GetReference());
118 }
119}
120
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800121template<size_t kNumReferences> template<class T>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700122inline MutableHandle<T> FixedSizeHandleScope<kNumReferences>::NewHandle(T* object) {
Vladimir Markoabedfca2019-05-23 14:07:47 +0100123 return NewHandle(ObjPtr<T>(object));
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800124}
125
Andreas Gampec73cb642017-02-22 10:11:30 -0800126template<size_t kNumReferences> template<class MirrorType>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700127inline MutableHandle<MirrorType> FixedSizeHandleScope<kNumReferences>::NewHandle(
Andreas Gampec73cb642017-02-22 10:11:30 -0800128 ObjPtr<MirrorType> object) {
Vladimir Markoabedfca2019-05-23 14:07:47 +0100129 SetReference(pos_, object);
130 MutableHandle<MirrorType> h(GetHandle<MirrorType>(pos_));
131 ++pos_;
132 return h;
Mathieu Chartier0795f232016-09-27 18:43:30 -0700133}
134
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800135template<size_t kNumReferences> template<class T>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700136inline HandleWrapper<T> FixedSizeHandleScope<kNumReferences>::NewHandleWrapper(T** object) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700137 return HandleWrapper<T>(object, NewHandle(*object));
138}
139
140template<size_t kNumReferences> template<class T>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700141inline HandleWrapperObjPtr<T> FixedSizeHandleScope<kNumReferences>::NewHandleWrapper(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700142 ObjPtr<T>* object) {
143 return HandleWrapperObjPtr<T>(object, NewHandle(*object));
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800144}
145
146template<size_t kNumReferences>
Vladimir Markoabedfca2019-05-23 14:07:47 +0100147inline void FixedSizeHandleScope<kNumReferences>::SetReference(size_t i,
148 ObjPtr<mirror::Object> object) {
Mathieu Chartiered150002015-08-28 11:16:54 -0700149 if (kDebugLocking) {
150 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
151 }
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800152 DCHECK_LT(i, kNumReferences);
153 VerifyObject(object);
154 GetReferences()[i].Assign(object);
155}
156
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700157// Number of references contained within this handle scope.
158inline uint32_t BaseHandleScope::NumberOfReferences() const {
159 return LIKELY(!IsVariableSized())
160 ? AsHandleScope()->NumberOfReferences()
161 : AsVariableSized()->NumberOfReferences();
162}
163
164inline bool BaseHandleScope::Contains(StackReference<mirror::Object>* handle_scope_entry) const {
165 return LIKELY(!IsVariableSized())
166 ? AsHandleScope()->Contains(handle_scope_entry)
167 : AsVariableSized()->Contains(handle_scope_entry);
168}
169
170template <typename Visitor>
171inline void BaseHandleScope::VisitRoots(Visitor& visitor) {
172 if (LIKELY(!IsVariableSized())) {
173 AsHandleScope()->VisitRoots(visitor);
174 } else {
175 AsVariableSized()->VisitRoots(visitor);
176 }
177}
178
179inline VariableSizedHandleScope* BaseHandleScope::AsVariableSized() {
180 DCHECK(IsVariableSized());
181 return down_cast<VariableSizedHandleScope*>(this);
182}
183
184inline HandleScope* BaseHandleScope::AsHandleScope() {
185 DCHECK(!IsVariableSized());
186 return down_cast<HandleScope*>(this);
187}
188
189inline const VariableSizedHandleScope* BaseHandleScope::AsVariableSized() const {
190 DCHECK(IsVariableSized());
191 return down_cast<const VariableSizedHandleScope*>(this);
192}
193
194inline const HandleScope* BaseHandleScope::AsHandleScope() const {
195 DCHECK(!IsVariableSized());
196 return down_cast<const HandleScope*>(this);
197}
198
199template<class T>
Vladimir Markoabedfca2019-05-23 14:07:47 +0100200inline MutableHandle<T> VariableSizedHandleScope::NewHandle(T* object) {
201 return NewHandle(ObjPtr<T>(object));
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700202}
203
Andreas Gampec73cb642017-02-22 10:11:30 -0800204template<class MirrorType>
205inline MutableHandle<MirrorType> VariableSizedHandleScope::NewHandle(ObjPtr<MirrorType> ptr) {
Vladimir Markoabedfca2019-05-23 14:07:47 +0100206 if (current_scope_->RemainingSlots() == 0) {
207 current_scope_ = new LocalScopeType(current_scope_);
208 }
209 return current_scope_->NewHandle(ptr);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700210}
211
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700212inline VariableSizedHandleScope::VariableSizedHandleScope(Thread* const self)
213 : BaseHandleScope(self->GetTopHandleScope()),
214 self_(self) {
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700215 current_scope_ = new LocalScopeType(/*link=*/ nullptr);
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700216 self_->PushHandleScope(this);
217}
218
219inline VariableSizedHandleScope::~VariableSizedHandleScope() {
220 BaseHandleScope* top_handle_scope = self_->PopHandleScope();
221 DCHECK_EQ(top_handle_scope, this);
222 while (current_scope_ != nullptr) {
223 LocalScopeType* next = reinterpret_cast<LocalScopeType*>(current_scope_->GetLink());
224 delete current_scope_;
225 current_scope_ = next;
226 }
227}
228
229inline uint32_t VariableSizedHandleScope::NumberOfReferences() const {
230 uint32_t sum = 0;
231 const LocalScopeType* cur = current_scope_;
232 while (cur != nullptr) {
233 sum += cur->NumberOfReferences();
234 cur = reinterpret_cast<const LocalScopeType*>(cur->GetLink());
235 }
236 return sum;
237}
238
239inline bool VariableSizedHandleScope::Contains(StackReference<mirror::Object>* handle_scope_entry)
240 const {
241 const LocalScopeType* cur = current_scope_;
242 while (cur != nullptr) {
243 if (cur->Contains(handle_scope_entry)) {
244 return true;
245 }
246 cur = reinterpret_cast<const LocalScopeType*>(cur->GetLink());
247 }
248 return false;
249}
250
251template <typename Visitor>
252inline void VariableSizedHandleScope::VisitRoots(Visitor& visitor) {
253 LocalScopeType* cur = current_scope_;
254 while (cur != nullptr) {
255 cur->VisitRoots(visitor);
256 cur = reinterpret_cast<LocalScopeType*>(cur->GetLink());
257 }
258}
259
260
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700261} // namespace art
262
263#endif // ART_RUNTIME_HANDLE_SCOPE_INL_H_