blob: 765ed7d53b2fa24fce4c6b154af1b9b148f5903a [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"
Mathieu Chartier0795f232016-09-27 18:43:30 -070025#include "obj_ptr-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070026#include "thread-current-inl.h"
Andreas Gampe90b936d2017-01-31 08:58:55 -080027#include "verify_object.h"
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070028
29namespace art {
30
31template<size_t kNumReferences>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070032inline FixedSizeHandleScope<kNumReferences>::FixedSizeHandleScope(BaseHandleScope* link,
33 mirror::Object* fill_value)
34 : HandleScope(link, kNumReferences) {
Mathieu Chartiered150002015-08-28 11:16:54 -070035 if (kDebugLocking) {
36 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
37 }
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070038 static_assert(kNumReferences >= 1, "FixedSizeHandleScope must contain at least 1 reference");
39 DCHECK_EQ(&storage_[0], GetReferences()); // TODO: Figure out how to use a compile assert.
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070040 for (size_t i = 0; i < kNumReferences; ++i) {
Mathieu Chartier2d2621a2014-10-23 16:48:06 -070041 SetReference(i, fill_value);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070042 }
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070043}
44
45template<size_t kNumReferences>
46inline StackHandleScope<kNumReferences>::StackHandleScope(Thread* self, mirror::Object* fill_value)
47 : FixedSizeHandleScope<kNumReferences>(self->GetTopHandleScope(), fill_value),
48 self_(self) {
49 DCHECK_EQ(self, Thread::Current());
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070050 self_->PushHandleScope(this);
51}
52
53template<size_t kNumReferences>
Mathieu Chartier421c5372014-05-14 14:11:40 -070054inline StackHandleScope<kNumReferences>::~StackHandleScope() {
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070055 BaseHandleScope* top_handle_scope = self_->PopHandleScope();
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070056 DCHECK_EQ(top_handle_scope, this);
Mathieu Chartiered150002015-08-28 11:16:54 -070057 if (kDebugLocking) {
58 Locks::mutator_lock_->AssertSharedHeld(self_);
59 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070060}
61
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080062inline size_t HandleScope::SizeOf(uint32_t num_references) {
63 size_t header_size = sizeof(HandleScope);
64 size_t data_size = sizeof(StackReference<mirror::Object>) * num_references;
65 return header_size + data_size;
66}
67
Andreas Gampe542451c2016-07-26 09:02:02 -070068inline size_t HandleScope::SizeOf(PointerSize pointer_size, uint32_t num_references) {
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080069 // Assume that the layout is packed.
Andreas Gampe542451c2016-07-26 09:02:02 -070070 size_t header_size = ReferencesOffset(pointer_size);
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080071 size_t data_size = sizeof(StackReference<mirror::Object>) * num_references;
72 return header_size + data_size;
73}
74
75inline mirror::Object* HandleScope::GetReference(size_t i) const {
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070076 DCHECK_LT(i, NumberOfReferences());
Mathieu Chartiered150002015-08-28 11:16:54 -070077 if (kDebugLocking) {
78 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
79 }
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080080 return GetReferences()[i].AsMirrorPtr();
81}
82
83inline Handle<mirror::Object> HandleScope::GetHandle(size_t i) {
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070084 DCHECK_LT(i, NumberOfReferences());
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080085 return Handle<mirror::Object>(&GetReferences()[i]);
86}
87
88inline MutableHandle<mirror::Object> HandleScope::GetMutableHandle(size_t i) {
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070089 DCHECK_LT(i, NumberOfReferences());
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080090 return MutableHandle<mirror::Object>(&GetReferences()[i]);
91}
92
93inline void HandleScope::SetReference(size_t i, mirror::Object* object) {
Mathieu Chartiered150002015-08-28 11:16:54 -070094 if (kDebugLocking) {
95 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
96 }
Mathieu Chartiere8a3c572016-10-11 16:52:17 -070097 DCHECK_LT(i, NumberOfReferences());
Mathieu Chartier3e0acf62015-01-08 09:41:25 -080098 GetReferences()[i].Assign(object);
99}
100
101inline bool HandleScope::Contains(StackReference<mirror::Object>* handle_scope_entry) const {
102 // A HandleScope should always contain something. One created by the
103 // jni_compiler should have a jobject/jclass as a native method is
104 // passed in a this pointer or a class
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700105 DCHECK_GT(NumberOfReferences(), 0U);
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800106 return &GetReferences()[0] <= handle_scope_entry &&
107 handle_scope_entry <= &GetReferences()[number_of_references_ - 1];
108}
109
Andreas Gampea1ffdba2019-01-04 16:08:51 -0800110template <typename Visitor>
111inline void HandleScope::VisitRoots(Visitor& visitor) {
112 for (size_t i = 0, count = NumberOfReferences(); i < count; ++i) {
113 // GetReference returns a pointer to the stack reference within the handle scope. If this
114 // needs to be updated, it will be done by the root visitor.
115 visitor.VisitRootIfNonNull(GetHandle(i).GetReference());
116 }
117}
118
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800119template<size_t kNumReferences> template<class T>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700120inline MutableHandle<T> FixedSizeHandleScope<kNumReferences>::NewHandle(T* object) {
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800121 SetReference(pos_, object);
122 MutableHandle<T> h(GetHandle<T>(pos_));
123 pos_++;
124 return h;
125}
126
Andreas Gampec73cb642017-02-22 10:11:30 -0800127template<size_t kNumReferences> template<class MirrorType>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700128inline MutableHandle<MirrorType> FixedSizeHandleScope<kNumReferences>::NewHandle(
Andreas Gampec73cb642017-02-22 10:11:30 -0800129 ObjPtr<MirrorType> object) {
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700130 return NewHandle(object.Ptr());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700131}
132
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800133template<size_t kNumReferences> template<class T>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700134inline HandleWrapper<T> FixedSizeHandleScope<kNumReferences>::NewHandleWrapper(T** object) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700135 return HandleWrapper<T>(object, NewHandle(*object));
136}
137
138template<size_t kNumReferences> template<class T>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700139inline HandleWrapperObjPtr<T> FixedSizeHandleScope<kNumReferences>::NewHandleWrapper(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700140 ObjPtr<T>* object) {
141 return HandleWrapperObjPtr<T>(object, NewHandle(*object));
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800142}
143
144template<size_t kNumReferences>
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700145inline void FixedSizeHandleScope<kNumReferences>::SetReference(size_t i, mirror::Object* object) {
Mathieu Chartiered150002015-08-28 11:16:54 -0700146 if (kDebugLocking) {
147 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
148 }
Mathieu Chartier3e0acf62015-01-08 09:41:25 -0800149 DCHECK_LT(i, kNumReferences);
150 VerifyObject(object);
151 GetReferences()[i].Assign(object);
152}
153
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700154// Number of references contained within this handle scope.
155inline uint32_t BaseHandleScope::NumberOfReferences() const {
156 return LIKELY(!IsVariableSized())
157 ? AsHandleScope()->NumberOfReferences()
158 : AsVariableSized()->NumberOfReferences();
159}
160
161inline bool BaseHandleScope::Contains(StackReference<mirror::Object>* handle_scope_entry) const {
162 return LIKELY(!IsVariableSized())
163 ? AsHandleScope()->Contains(handle_scope_entry)
164 : AsVariableSized()->Contains(handle_scope_entry);
165}
166
167template <typename Visitor>
168inline void BaseHandleScope::VisitRoots(Visitor& visitor) {
169 if (LIKELY(!IsVariableSized())) {
170 AsHandleScope()->VisitRoots(visitor);
171 } else {
172 AsVariableSized()->VisitRoots(visitor);
173 }
174}
175
176inline VariableSizedHandleScope* BaseHandleScope::AsVariableSized() {
177 DCHECK(IsVariableSized());
178 return down_cast<VariableSizedHandleScope*>(this);
179}
180
181inline HandleScope* BaseHandleScope::AsHandleScope() {
182 DCHECK(!IsVariableSized());
183 return down_cast<HandleScope*>(this);
184}
185
186inline const VariableSizedHandleScope* BaseHandleScope::AsVariableSized() const {
187 DCHECK(IsVariableSized());
188 return down_cast<const VariableSizedHandleScope*>(this);
189}
190
191inline const HandleScope* BaseHandleScope::AsHandleScope() const {
192 DCHECK(!IsVariableSized());
193 return down_cast<const HandleScope*>(this);
194}
195
196template<class T>
197MutableHandle<T> VariableSizedHandleScope::NewHandle(T* object) {
198 if (current_scope_->RemainingSlots() == 0) {
199 current_scope_ = new LocalScopeType(current_scope_);
200 }
201 return current_scope_->NewHandle(object);
202}
203
Andreas Gampec73cb642017-02-22 10:11:30 -0800204template<class MirrorType>
205inline MutableHandle<MirrorType> VariableSizedHandleScope::NewHandle(ObjPtr<MirrorType> ptr) {
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700206 return NewHandle(ptr.Ptr());
Mathieu Chartier3398c782016-09-30 10:27:43 -0700207}
208
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700209inline VariableSizedHandleScope::VariableSizedHandleScope(Thread* const self)
210 : BaseHandleScope(self->GetTopHandleScope()),
211 self_(self) {
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700212 current_scope_ = new LocalScopeType(/*link=*/ nullptr);
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700213 self_->PushHandleScope(this);
214}
215
216inline VariableSizedHandleScope::~VariableSizedHandleScope() {
217 BaseHandleScope* top_handle_scope = self_->PopHandleScope();
218 DCHECK_EQ(top_handle_scope, this);
219 while (current_scope_ != nullptr) {
220 LocalScopeType* next = reinterpret_cast<LocalScopeType*>(current_scope_->GetLink());
221 delete current_scope_;
222 current_scope_ = next;
223 }
224}
225
226inline uint32_t VariableSizedHandleScope::NumberOfReferences() const {
227 uint32_t sum = 0;
228 const LocalScopeType* cur = current_scope_;
229 while (cur != nullptr) {
230 sum += cur->NumberOfReferences();
231 cur = reinterpret_cast<const LocalScopeType*>(cur->GetLink());
232 }
233 return sum;
234}
235
236inline bool VariableSizedHandleScope::Contains(StackReference<mirror::Object>* handle_scope_entry)
237 const {
238 const LocalScopeType* cur = current_scope_;
239 while (cur != nullptr) {
240 if (cur->Contains(handle_scope_entry)) {
241 return true;
242 }
243 cur = reinterpret_cast<const LocalScopeType*>(cur->GetLink());
244 }
245 return false;
246}
247
248template <typename Visitor>
249inline void VariableSizedHandleScope::VisitRoots(Visitor& visitor) {
250 LocalScopeType* cur = current_scope_;
251 while (cur != nullptr) {
252 cur->VisitRoots(visitor);
253 cur = reinterpret_cast<LocalScopeType*>(cur->GetLink());
254 }
255}
256
257
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700258} // namespace art
259
260#endif // ART_RUNTIME_HANDLE_SCOPE_INL_H_