• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 PANDA_RUNTIME_PANDA_VM_H_
16 #define PANDA_RUNTIME_PANDA_VM_H_
17 
18 #include "include/coretypes/string.h"
19 #include "include/runtime_options.h"
20 #include "runtime/include/locks.h"
21 #include "runtime/include/mem/panda_containers.h"
22 #include "runtime/include/mem/panda_string.h"
23 #include "runtime/include/method.h"
24 #include "runtime/include/runtime.h"
25 #include "runtime/mem/gc/gc_phase.h"
26 
27 #include "libpandabase/utils/expected.h"
28 
29 namespace ark {
30 
31 class ManagedThread;
32 class StringTable;
33 class ThreadManager;
34 
35 namespace compiler {
36 class RuntimeInterface;
37 }  // namespace compiler
38 
39 namespace mem {
40 class HeapManager;
41 class GC;
42 class GCTrigger;
43 class ReferenceProcessor;
44 }  // namespace mem
45 
46 enum class PandaVMType : size_t { ECMA_VM };  // Deprecated. Only for Compability with js_runtime.
47 
48 class PandaVM {
49 public:
50     static PandaVM *Create(Runtime *runtime, const RuntimeOptions &options, std::string_view runtimeType);
51 
PandaVM()52     explicit PandaVM() : mutatorLock_(Locks::NewMutatorLock()) {};
53 
54     virtual ~PandaVM() = default;
55 
GetCurrent()56     static PandaVM *GetCurrent()
57     {
58         ASSERT(Thread::GetCurrent() != nullptr);
59         return Thread::GetCurrent()->GetVM();
60     }
61 
ResolveString(const panda_file::File & pf,panda_file::File::EntityId id)62     virtual coretypes::String *ResolveString([[maybe_unused]] const panda_file::File &pf,
63                                              [[maybe_unused]] panda_file::File::EntityId id)
64     {
65         return nullptr;
66     }
67     virtual bool Initialize() = 0;
68     virtual bool InitializeFinish() = 0;
69     virtual void PreStartup() = 0;
70     virtual void PreZygoteFork() = 0;
71     virtual void PostZygoteFork() = 0;
72     virtual void InitializeGC() = 0;
73     virtual void StartGC() = 0;
74     virtual void StopGC() = 0;
75     virtual void VisitVmRoots(const GCRootVisitor &visitor);
76     virtual void UpdateVmRefs();
77     virtual void UninitializeThreads() = 0;
SaveProfileInfo()78     virtual void SaveProfileInfo() {}
79 
80     virtual Expected<int, Runtime::Error> InvokeEntrypoint(Method *entrypoint, const std::vector<std::string> &args);
81 
82     // NOLINTNEXTLINE(performance-unnecessary-value-param)
HandleReferences(const GCTask & task,const mem::GC::ReferenceClearPredicateT & pred)83     virtual void HandleReferences([[maybe_unused]] const GCTask &task,
84                                   [[maybe_unused]] const mem::GC::ReferenceClearPredicateT &pred)
85     {
86     }
87 
HandleEnqueueReferences()88     virtual void HandleEnqueueReferences() {}
HandleGCFinished()89     virtual void HandleGCFinished() {}
90     /*
91      * Handle some vm related routine (e.g. finalization calls) after GC.
92      * Method will be called only in a mutator thread
93      */
HandleGCRoutineInMutator()94     virtual void HandleGCRoutineInMutator() {}
95     virtual void HandleLdaStr(Frame *frame, BytecodeId stringId);
HandleReturnFrame()96     virtual void HandleReturnFrame() {}
97     virtual void ProcessReferenceFinalizers();
98 
99     virtual mem::GCStats *GetGCStats() const = 0;
100     virtual mem::HeapManager *GetHeapManager() const = 0;
101     virtual mem::GC *GetGC() const = 0;
102     virtual mem::GCTrigger *GetGCTrigger() const = 0;
103     virtual const RuntimeOptions &GetOptions() const = 0;
104     virtual ManagedThread *GetAssociatedThread() const = 0;
105     virtual StringTable *GetStringTable() const = 0;
106     virtual mem::MemStatsType *GetMemStats() const = 0;
107     virtual Rendezvous *GetRendezvous() const = 0;
108     virtual mem::GlobalObjectStorage *GetGlobalObjectStorage() const = 0;
109     virtual MonitorPool *GetMonitorPool() const = 0;
110     virtual ThreadManager *GetThreadManager() const = 0;
CreateString(Method * ctor,ObjectHeader * obj)111     virtual coretypes::String *CreateString([[maybe_unused]] Method *ctor, [[maybe_unused]] ObjectHeader *obj)
112     {
113         UNREACHABLE();
114         return nullptr;
115     }
GetCompilerRuntimeInterface()116     virtual compiler::RuntimeInterface *GetCompilerRuntimeInterface() const
117     {
118         return nullptr;
119     }
VisitStringTable(const StringTable::StringVisitor & visitor,mem::VisitGCRootFlags flags)120     virtual void VisitStringTable(const StringTable::StringVisitor &visitor, mem::VisitGCRootFlags flags)
121     {
122         GetStringTable()->VisitRoots(visitor, flags);
123     }
124 
VisitStrings(const StringTable::StringVisitor & visitor)125     virtual void VisitStrings(const StringTable::StringVisitor &visitor)
126     {
127         GetStringTable()->VisitStrings(visitor);
128     }
129 
SweepVmRefs(const GCObjectVisitor & gcObjectVisitor)130     virtual void SweepVmRefs(const GCObjectVisitor &gcObjectVisitor)
131     {
132         GetStringTable()->Sweep(gcObjectVisitor);
133     }
134 
UpdateMovedStrings()135     virtual bool UpdateMovedStrings()
136     {
137         return GetStringTable()->UpdateMoved();
138     }
139 
140     // NOTE(maksenov): remove this method after fixing interpreter performance
GetPandaVMType()141     virtual PandaVMType GetPandaVMType() const
142     {
143         // Deprecated. Only for Compability with js_runtime.
144         return PandaVMType::ECMA_VM;
145     }
146 
147     virtual LanguageContext GetLanguageContext() const = 0;
148     virtual CompilerInterface *GetCompiler() const = 0;
149 
150     virtual ark::mem::ReferenceProcessor *GetReferenceProcessor() const = 0;
151 
152     virtual ObjectHeader *GetOOMErrorObject() = 0;
153 
RegisterSignalHandlers()154     virtual void RegisterSignalHandlers() {};
155 
DumpForSigQuit(std::ostream & os)156     virtual void DumpForSigQuit([[maybe_unused]] std::ostream &os) const {};
157 
158     virtual std::unique_ptr<const panda_file::File> OpenPandaFile(std::string_view location);
159 
ResolveStringFromCompiledCode(const panda_file::File & pf,panda_file::File::EntityId id)160     virtual coretypes::String *ResolveStringFromCompiledCode(const panda_file::File &pf, panda_file::File::EntityId id)
161     {
162         return ResolveString(pf, id);
163     }
164 
ResolveString(Frame * frame,panda_file::File::EntityId id)165     virtual coretypes::String *ResolveString([[maybe_unused]] Frame *frame,
166                                              [[maybe_unused]] panda_file::File::EntityId id)
167     {
168         return nullptr;
169     }
170 
171     virtual coretypes::String *GetNonMovableString(const panda_file::File &pf, panda_file::File::EntityId id) const;
172 
GetFrameExtSize()173     uint32_t GetFrameExtSize() const
174     {
175         return frameExtSize_;
176     }
177 
IsBytecodeProfilingEnabled()178     virtual bool IsBytecodeProfilingEnabled() const
179     {
180         return false;
181     }
182 
CleanUpTask(Method * method)183     virtual void CleanUpTask([[maybe_unused]] Method *method) {};
184 
185     virtual bool ShouldEnableDebug();
186 
IsStaticProfileEnabled()187     virtual bool IsStaticProfileEnabled() const
188     {
189         return false;
190     }
191 
DumpHeap(PandaOStringStream * oStr)192     virtual void DumpHeap(PandaOStringStream *oStr) const
193     {
194         size_t objCnt = 0;
195         *oStr << "Dumping heap" << std::endl;
196         GetHeapManager()->IterateOverObjects([&objCnt, &oStr](ObjectHeader *mem) {
197             DumpObject(mem, oStr);
198             objCnt++;
199         });
200         *oStr << "Total dumped " << objCnt << std::endl;
201     }
202 
203     virtual PandaString GetClassesFootprint() const;
204 
LoadDebuggerAgent()205     void LoadDebuggerAgent()
206     {
207         debuggerAgent_ = CreateDebuggerAgent();
208     }
209 
UnloadDebuggerAgent()210     void UnloadDebuggerAgent()
211     {
212         debuggerAgent_.reset();
213     }
214 
GetMutatorLock()215     MutatorLock *GetMutatorLock()
216     {
217         return mutatorLock_;
218     }
219 
GetMutatorLock()220     const MutatorLock *GetMutatorLock() const
221     {
222         return mutatorLock_;
223     }
224 
225     // Intrusive GC test API
226     void MarkObject(ObjectHeader *obj);
227     void IterateOverMarkQueue(const std::function<void(ObjectHeader *)> &visitor);
228     void ClearMarkQueue();
229 
ClearInteropHandleScopes(Frame * frame)230     virtual void ClearInteropHandleScopes([[maybe_unused]] Frame *frame) {}
231 
SupportGCSinglePassCompaction()232     virtual bool SupportGCSinglePassCompaction() const
233     {
234         return false;
235     }
236 
237     NO_MOVE_SEMANTIC(PandaVM);
238     NO_COPY_SEMANTIC(PandaVM);
239 
240 protected:
241     virtual bool CheckEntrypointSignature(Method *entrypoint) = 0;
242     virtual Expected<int, Runtime::Error> InvokeEntrypointImpl(Method *entrypoint,
243                                                                const std::vector<std::string> &args) = 0;
244     virtual void HandleUncaughtException() = 0;
245 
SetFrameExtSize(uint32_t size)246     void SetFrameExtSize(uint32_t size)
247     {
248         frameExtSize_ = size;
249     }
250 
251     virtual LoadableAgentHandle CreateDebuggerAgent();
252 
253 private:
254     /// Lock used for preventing object heap modifications (for example at GC<->JIT,ManagedCode interaction during STW)
255     MutatorLock *mutatorLock_;
256     uint32_t frameExtSize_ {EMPTY_EXT_FRAME_DATA_SIZE};
257     LoadableAgentHandle debuggerAgent_;
258 
259     // Intrusive GC test API
260     PandaList<ObjectHeader *> markQueue_ GUARDED_BY(markQueueLock_);
261     os::memory::Mutex markQueueLock_;
262 };
263 
264 }  // namespace ark
265 
266 #endif  // PANDA_RUNTIME_PANDA_VM_H_
267