• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)31 PtGlobalReference *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)39 void 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)47 PtLocalReference *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)55 void 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()64 void 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()72 void PtPopLocalFrameFromNative()
73 {
74     ASSERT_NATIVE_CODE();
75     auto *thread = MTManagedThread::GetCurrent();
76     thread->GetPtReferenceStorage()->PopLocalFrame(nullptr);
77 }
78 
PtCreateLocalReference(ObjectHeader * objectHeader)79 PtLocalReference *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)88 void 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)97 ObjectHeader *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)106 PtGlobalReference *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)115 PtGlobalReference *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)125 void 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