• 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();
BeforeShutdown()98     virtual void BeforeShutdown() {}
99 
100     virtual mem::GCStats *GetGCStats() const = 0;
101     virtual mem::HeapManager *GetHeapManager() const = 0;
102     virtual mem::GC *GetGC() const = 0;
103     virtual mem::GCTrigger *GetGCTrigger() const = 0;
104     virtual const RuntimeOptions &GetOptions() const = 0;
105     virtual ManagedThread *GetAssociatedThread() const = 0;
106     virtual StringTable *GetStringTable() const = 0;
107     virtual mem::MemStatsType *GetMemStats() const = 0;
108     virtual Rendezvous *GetRendezvous() const = 0;
109     virtual mem::GlobalObjectStorage *GetGlobalObjectStorage() const = 0;
110     virtual MonitorPool *GetMonitorPool() const = 0;
111     virtual ThreadManager *GetThreadManager() const = 0;
CreateString(Method * ctor,ObjectHeader * obj)112     virtual coretypes::String *CreateString([[maybe_unused]] Method *ctor, [[maybe_unused]] ObjectHeader *obj)
113     {
114         UNREACHABLE();
115         return nullptr;
116     }
GetCompilerRuntimeInterface()117     virtual compiler::RuntimeInterface *GetCompilerRuntimeInterface() const
118     {
119         return nullptr;
120     }
VisitStringTable(const StringTable::StringVisitor & visitor,mem::VisitGCRootFlags flags)121     virtual void VisitStringTable(const StringTable::StringVisitor &visitor, mem::VisitGCRootFlags flags)
122     {
123         GetStringTable()->VisitRoots(visitor, flags);
124     }
125 
VisitStrings(const StringTable::StringVisitor & visitor)126     virtual void VisitStrings(const StringTable::StringVisitor &visitor)
127     {
128         GetStringTable()->VisitStrings(visitor);
129     }
130 
SweepVmRefs(const GCObjectVisitor & gcObjectVisitor)131     virtual void SweepVmRefs(const GCObjectVisitor &gcObjectVisitor)
132     {
133         GetStringTable()->Sweep(gcObjectVisitor);
134     }
135 
UpdateMovedStrings()136     virtual bool UpdateMovedStrings()
137     {
138         return GetStringTable()->UpdateMoved();
139     }
140 
141     // NOTE(maksenov): remove this method after fixing interpreter performance
GetPandaVMType()142     virtual PandaVMType GetPandaVMType() const
143     {
144         // Deprecated. Only for Compability with js_runtime.
145         return PandaVMType::ECMA_VM;
146     }
147 
148     virtual LanguageContext GetLanguageContext() const = 0;
149     virtual CompilerInterface *GetCompiler() const = 0;
150 
151     virtual ark::mem::ReferenceProcessor *GetReferenceProcessor() const = 0;
152 
153     virtual ObjectHeader *GetOOMErrorObject() = 0;
154 
RegisterSignalHandlers()155     virtual void RegisterSignalHandlers() {};
156 
DumpForSigQuit(std::ostream & os)157     virtual void DumpForSigQuit([[maybe_unused]] std::ostream &os) const {};
158 
159     virtual std::unique_ptr<const panda_file::File> OpenPandaFile(std::string_view location);
160 
ResolveStringFromCompiledCode(const panda_file::File & pf,panda_file::File::EntityId id)161     virtual coretypes::String *ResolveStringFromCompiledCode(const panda_file::File &pf, panda_file::File::EntityId id)
162     {
163         return ResolveString(pf, id);
164     }
165 
ResolveString(Frame * frame,panda_file::File::EntityId id)166     virtual coretypes::String *ResolveString([[maybe_unused]] Frame *frame,
167                                              [[maybe_unused]] panda_file::File::EntityId id)
168     {
169         return nullptr;
170     }
171 
172     virtual coretypes::String *GetNonMovableString(const panda_file::File &pf, panda_file::File::EntityId id) const;
173 
GetFrameExtSize()174     uint32_t GetFrameExtSize() const
175     {
176         return frameExtSize_;
177     }
178 
IsBytecodeProfilingEnabled()179     virtual bool IsBytecodeProfilingEnabled() const
180     {
181         return false;
182     }
183 
CleanUpTask(Method * method)184     virtual void CleanUpTask([[maybe_unused]] Method *method) {};
185 
186     virtual bool ShouldEnableDebug();
187 
IsStaticProfileEnabled()188     virtual bool IsStaticProfileEnabled() const
189     {
190         return false;
191     }
192 
DumpHeap(PandaOStringStream * oStr)193     virtual void DumpHeap(PandaOStringStream *oStr) const
194     {
195         size_t objCnt = 0;
196         *oStr << "Dumping heap" << std::endl;
197         GetHeapManager()->IterateOverObjects([&objCnt, &oStr](ObjectHeader *mem) {
198             DumpObject(mem, oStr);
199             objCnt++;
200         });
201         *oStr << "Total dumped " << objCnt << std::endl;
202     }
203 
204     virtual PandaString GetClassesFootprint() const;
205 
LoadDebuggerAgent()206     void LoadDebuggerAgent()
207     {
208         debuggerAgent_ = CreateDebuggerAgent();
209     }
210 
UnloadDebuggerAgent()211     void UnloadDebuggerAgent()
212     {
213         debuggerAgent_.reset();
214     }
215 
GetMutatorLock()216     MutatorLock *GetMutatorLock()
217     {
218         return mutatorLock_;
219     }
220 
GetMutatorLock()221     const MutatorLock *GetMutatorLock() const
222     {
223         return mutatorLock_;
224     }
225 
226     // Intrusive GC test API
227     void MarkObject(ObjectHeader *obj);
228     void IterateOverMarkQueue(const std::function<void(ObjectHeader *)> &visitor);
229     void ClearMarkQueue();
230 
ClearInteropHandleScopes(Frame * frame)231     virtual void ClearInteropHandleScopes([[maybe_unused]] Frame *frame) {}
232 
SupportGCSinglePassCompaction()233     virtual bool SupportGCSinglePassCompaction() const
234     {
235         return false;
236     }
237 
238     NO_MOVE_SEMANTIC(PandaVM);
239     NO_COPY_SEMANTIC(PandaVM);
240 
241 protected:
242     virtual bool CheckEntrypointSignature(Method *entrypoint) = 0;
243     virtual Expected<int, Runtime::Error> InvokeEntrypointImpl(Method *entrypoint,
244                                                                const std::vector<std::string> &args) = 0;
245     virtual void HandleUncaughtException() = 0;
246 
SetFrameExtSize(uint32_t size)247     void SetFrameExtSize(uint32_t size)
248     {
249         frameExtSize_ = size;
250     }
251 
252     virtual LoadableAgentHandle CreateDebuggerAgent();
253 
254 private:
255     /// Lock used for preventing object heap modifications (for example at GC<->JIT,ManagedCode interaction during STW)
256     MutatorLock *mutatorLock_;
257     uint32_t frameExtSize_ {EMPTY_EXT_FRAME_DATA_SIZE};
258     LoadableAgentHandle debuggerAgent_;
259 
260     // Intrusive GC test API
261     PandaList<ObjectHeader *> markQueue_ GUARDED_BY(markQueueLock_);
262     os::memory::Mutex markQueueLock_;
263 };
264 
265 }  // namespace ark
266 
267 #endif  // PANDA_RUNTIME_PANDA_VM_H_
268