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