1 /* 2 * Copyright (c) 2021 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 16 #include "runtime/include/tooling/pt_reference.h" 17 18 #include "pt_reference_private.h" 19 #include "pt_scoped_managed_code.h" 20 #include "runtime/include/thread_scopes.h" 21 #include "runtime/mem/refstorage/reference_storage.h" 22 #include "runtime/mem/refstorage/global_object_storage.h" 23 24 // NOLINTNEXTLINE 25 #define ASSERT_IS_NATIVE_CODE() \ 26 ASSERT(panda::MTManagedThread::GetCurrent() != nullptr && panda::MTManagedThread::GetCurrent()->IsInNativeCode()) 27 28 namespace panda::tooling { 29 30 /* static */ Create(PtReference * ref)31PtGlobalReference *PtGlobalReference::Create(PtReference *ref) 32 { 33 ASSERT_IS_NATIVE_CODE(); 34 ScopedManagedCodeThread smt(MTManagedThread::GetCurrent()); 35 return PtCreateGlobalReference(ref); 36 } 37 38 /* static */ Remove(PtGlobalReference * globalRef)39void PtGlobalReference::Remove(PtGlobalReference *globalRef) 40 { 41 ASSERT_IS_NATIVE_CODE(); 42 ScopedManagedCodeThread smt(MTManagedThread::GetCurrent()); 43 PtDestroyGlobalReference(globalRef); 44 } 45 46 /* static */ Create(PtReference * ref)47PtLocalReference *PtLocalReference::Create(PtReference *ref) 48 { 49 ASSERT_IS_NATIVE_CODE(); 50 ScopedManagedCodeThread smt(MTManagedThread::GetCurrent()); 51 return PtCreateLocalReference(PtGetObjectHeaderByReference(ref)); 52 } 53 54 /* static */ Remove(PtLocalReference * localRef)55void PtLocalReference::Remove(PtLocalReference *localRef) 56 { 57 ASSERT_IS_NATIVE_CODE(); 58 ScopedManagedCodeThread smt(MTManagedThread::GetCurrent()); 59 PtDestroyLocalReference(localRef); 60 } 61 62 // ====== Private API ====== 63 PtPushLocalFrameFromNative()64void PtPushLocalFrameFromNative() 65 { 66 ASSERT_NATIVE_CODE(); 67 auto *thread = MTManagedThread::GetCurrent(); 68 const uint32_t MAX_localRef = 4096; 69 thread->GetPtReferenceStorage()->PushLocalFrame(MAX_localRef); 70 } 71 PtPopLocalFrameFromNative()72void PtPopLocalFrameFromNative() 73 { 74 ASSERT_NATIVE_CODE(); 75 auto *thread = MTManagedThread::GetCurrent(); 76 thread->GetPtReferenceStorage()->PopLocalFrame(nullptr); 77 } 78 PtCreateLocalReference(ObjectHeader * objectHeader)79PtLocalReference *PtCreateLocalReference(ObjectHeader *objectHeader) 80 { 81 ASSERT(objectHeader != nullptr); 82 ASSERT_MANAGED_CODE(); 83 auto *thread = MTManagedThread::GetCurrent(); 84 auto *rs_ref = thread->GetPtReferenceStorage()->NewRef(objectHeader, mem::Reference::ObjectType::LOCAL); 85 return reinterpret_cast<PtLocalReference *>(rs_ref); 86 } 87 PtDestroyLocalReference(const PtLocalReference * localRef)88void PtDestroyLocalReference(const PtLocalReference *localRef) 89 { 90 ASSERT(localRef != nullptr); 91 ASSERT_MANAGED_CODE(); 92 auto *thread = MTManagedThread::GetCurrent(); 93 auto *rs_ref = reinterpret_cast<const mem::Reference *>(localRef); 94 thread->GetPtReferenceStorage()->RemoveRef(rs_ref); 95 } 96 PtGetObjectHeaderByReference(const PtReference * ref)97ObjectHeader *PtGetObjectHeaderByReference(const PtReference *ref) 98 { 99 ASSERT(ref != nullptr); 100 ASSERT_MANAGED_CODE(); 101 auto *thread = MTManagedThread::GetCurrent(); 102 auto *rs_ref = reinterpret_cast<const mem::Reference *>(ref); 103 return thread->GetPtReferenceStorage()->GetObject(rs_ref); 104 } 105 PtCreateGlobalReference(const ObjectHeader * objectHeader)106PtGlobalReference *PtCreateGlobalReference(const ObjectHeader *objectHeader) 107 { 108 ASSERT(objectHeader != nullptr); 109 ASSERT_MANAGED_CODE(); 110 auto newRef = 111 PandaVM::GetCurrent()->GetGlobalObjectStorage()->Add(objectHeader, mem::Reference::ObjectType::GLOBAL); 112 return reinterpret_cast<PtGlobalReference *>(newRef); 113 } 114 PtCreateGlobalReference(const PtReference * ref)115PtGlobalReference *PtCreateGlobalReference(const PtReference *ref) 116 { 117 ASSERT(ref != nullptr); 118 ASSERT_MANAGED_CODE(); 119 auto objectHeader = PtGetObjectHeaderByReference(ref); 120 auto newRef = 121 PandaVM::GetCurrent()->GetGlobalObjectStorage()->Add(objectHeader, mem::Reference::ObjectType::GLOBAL); 122 return reinterpret_cast<PtGlobalReference *>(newRef); 123 } 124 PtDestroyGlobalReference(const PtGlobalReference * globalRef)125void PtDestroyGlobalReference(const PtGlobalReference *globalRef) 126 { 127 ASSERT(globalRef != nullptr); 128 ASSERT_MANAGED_CODE(); 129 auto ref = reinterpret_cast<const mem::Reference *>(globalRef); 130 PandaVM::GetCurrent()->GetGlobalObjectStorage()->Remove(ref); 131 } 132 } // namespace panda::tooling 133