1 /* 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 20 #include "handle_scope.h" 21 22 #include "handle.h" 23 #include "thread.h" 24 #include "verify_object-inl.h" 25 26 namespace art { 27 28 template<size_t kNumReferences> 29 inline StackHandleScope<kNumReferences>::StackHandleScope(Thread* self, mirror::Object* fill_value) 30 : HandleScope(self->GetTopHandleScope(), kNumReferences), self_(self), pos_(0) { 31 DCHECK_EQ(self, Thread::Current()); 32 static_assert(kNumReferences >= 1, "StackHandleScope must contain at least 1 reference"); 33 // TODO: Figure out how to use a compile assert. 34 CHECK_EQ(&storage_[0], GetReferences()); 35 for (size_t i = 0; i < kNumReferences; ++i) { 36 SetReference(i, fill_value); 37 } 38 self_->PushHandleScope(this); 39 } 40 41 template<size_t kNumReferences> 42 inline StackHandleScope<kNumReferences>::~StackHandleScope() { 43 HandleScope* top_handle_scope = self_->PopHandleScope(); 44 DCHECK_EQ(top_handle_scope, this); 45 } 46 47 inline size_t HandleScope::SizeOf(uint32_t num_references) { 48 size_t header_size = sizeof(HandleScope); 49 size_t data_size = sizeof(StackReference<mirror::Object>) * num_references; 50 return header_size + data_size; 51 } 52 53 inline size_t HandleScope::SizeOf(size_t pointer_size, uint32_t num_references) { 54 // Assume that the layout is packed. 55 size_t header_size = pointer_size + sizeof(number_of_references_); 56 size_t data_size = sizeof(StackReference<mirror::Object>) * num_references; 57 return header_size + data_size; 58 } 59 60 inline mirror::Object* HandleScope::GetReference(size_t i) const { 61 DCHECK_LT(i, number_of_references_); 62 return GetReferences()[i].AsMirrorPtr(); 63 } 64 65 inline Handle<mirror::Object> HandleScope::GetHandle(size_t i) { 66 DCHECK_LT(i, number_of_references_); 67 return Handle<mirror::Object>(&GetReferences()[i]); 68 } 69 70 inline MutableHandle<mirror::Object> HandleScope::GetMutableHandle(size_t i) { 71 DCHECK_LT(i, number_of_references_); 72 return MutableHandle<mirror::Object>(&GetReferences()[i]); 73 } 74 75 inline void HandleScope::SetReference(size_t i, mirror::Object* object) { 76 DCHECK_LT(i, number_of_references_); 77 GetReferences()[i].Assign(object); 78 } 79 80 inline bool HandleScope::Contains(StackReference<mirror::Object>* handle_scope_entry) const { 81 // A HandleScope should always contain something. One created by the 82 // jni_compiler should have a jobject/jclass as a native method is 83 // passed in a this pointer or a class 84 DCHECK_GT(number_of_references_, 0U); 85 return &GetReferences()[0] <= handle_scope_entry && 86 handle_scope_entry <= &GetReferences()[number_of_references_ - 1]; 87 } 88 89 template<size_t kNumReferences> template<class T> 90 inline MutableHandle<T> StackHandleScope<kNumReferences>::NewHandle(T* object) { 91 SetReference(pos_, object); 92 MutableHandle<T> h(GetHandle<T>(pos_)); 93 pos_++; 94 return h; 95 } 96 97 template<size_t kNumReferences> template<class T> 98 inline HandleWrapper<T> StackHandleScope<kNumReferences>::NewHandleWrapper(T** object) { 99 SetReference(pos_, *object); 100 MutableHandle<T> h(GetHandle<T>(pos_)); 101 pos_++; 102 return HandleWrapper<T>(object, h); 103 } 104 105 template<size_t kNumReferences> 106 inline void StackHandleScope<kNumReferences>::SetReference(size_t i, mirror::Object* object) { 107 DCHECK_LT(i, kNumReferences); 108 VerifyObject(object); 109 GetReferences()[i].Assign(object); 110 } 111 112 } // namespace art 113 114 #endif // ART_RUNTIME_HANDLE_SCOPE_INL_H_ 115