1 /** 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef RUNTIME_MEM_OBJECT_VMHANDLE_H 16 #define RUNTIME_MEM_OBJECT_VMHANDLE_H 17 18 #include "libpandabase/macros.h" 19 #include "runtime/handle_base.h" 20 #include "runtime/include/managed_thread.h" 21 #include "runtime/handle_scope.h" 22 23 namespace ark { 24 25 using TaggedType = coretypes::TaggedType; 26 using TaggedValue = coretypes::TaggedValue; 27 28 template <typename T> 29 class LocalObjectHandle; 30 31 // VMHandle should be used in language-agnostic part of runtime 32 template <typename T> 33 class VMHandle : public HandleBase { 34 public: VMHandle()35 inline explicit VMHandle() : HandleBase(reinterpret_cast<uintptr_t>(nullptr)) {} 36 VMHandle(ManagedThread * thread,ObjectHeader * object)37 explicit VMHandle(ManagedThread *thread, ObjectHeader *object) 38 { 39 if (object != nullptr) { 40 auto scope = thread->GetTopScope<ObjectHeader *>(); 41 ASSERT(scope != nullptr); 42 address_ = scope->NewHandle(object); 43 } else { 44 address_ = reinterpret_cast<uintptr_t>(nullptr); 45 } 46 } 47 48 template <typename P, typename = std::enable_if_t<std::is_convertible_v<P *, T *>>> VMHandle(const VMHandle<P> & other)49 inline explicit VMHandle(const VMHandle<P> &other) : HandleBase(other.GetAddress()) 50 { 51 } 52 53 template <typename P, typename = std::enable_if_t<std::is_convertible_v<P *, T *>>> 54 inline explicit VMHandle(const LocalObjectHandle<P> &other); 55 56 inline explicit VMHandle(mem::GlobalObjectStorage *globalStorage, mem::Reference *reference); 57 58 ~VMHandle() = default; 59 60 DEFAULT_COPY_SEMANTIC(VMHandle); 61 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(VMHandle); 62 GetPtr()63 T *GetPtr() const 64 { 65 if (address_ == reinterpret_cast<uintptr_t>(nullptr)) { 66 return nullptr; 67 } 68 return *(reinterpret_cast<T **>(GetAddress())); 69 } 70 71 explicit operator T *() 72 { 73 return GetPtr(); 74 } 75 76 T *operator->() 77 { 78 return GetPtr(); 79 } 80 }; 81 82 template <typename T> 83 class VMMutableHandle : public VMHandle<T> { 84 public: VMMutableHandle(ManagedThread * thread,ObjectHeader * object)85 VMMutableHandle(ManagedThread *thread, ObjectHeader *object) 86 { 87 scope_ = thread->GetTopScope<ObjectHeader *>(); 88 ASSERT(scope_ != nullptr); 89 if (object != nullptr) { 90 this->address_ = scope_->NewHandle(object); 91 } else { 92 this->address_ = reinterpret_cast<uintptr_t>(nullptr); 93 } 94 } 95 ~VMMutableHandle() = default; 96 Update(ObjectHeader * object)97 void Update(ObjectHeader *object) 98 { 99 ASSERT(object != nullptr); 100 if (this->address_ == reinterpret_cast<uintptr_t>(nullptr)) { 101 this->address_ = scope_->NewHandle(object); 102 } else { 103 *reinterpret_cast<ObjectHeader **>(this->address_) = object; 104 } 105 } 106 107 NO_COPY_SEMANTIC(VMMutableHandle); 108 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(VMMutableHandle); 109 110 private: 111 HandleScope<ObjectHeader *> *scope_ {nullptr}; 112 }; 113 } // namespace ark 114 115 #endif // RUNTIME_MEM_OBJECT_VMHANDLE_H 116