1 /* 2 * Copyright (c) 2023-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 ECMASCRIPT_ECMA_CONTEXT_H 16 #define ECMASCRIPT_ECMA_CONTEXT_H 17 18 #include <cstdint> 19 #include <optional> 20 #include "ecmascript/base/aligned_struct.h" 21 #include "ecmascript/base/config.h" 22 #include "ecmascript/common.h" 23 #include "ecmascript/dfx/vmstat/opt_code_profiler.h" 24 #include "ecmascript/frames.h" 25 #include "ecmascript/ic/mega_ic_cache.h" 26 #include "ecmascript/js_handle.h" 27 #include "ecmascript/js_tagged_value.h" 28 #include "ecmascript/mem/c_containers.h" 29 #include "ecmascript/mem/visitor.h" 30 #include "ecmascript/module/js_module_execute_type.h" 31 #include "ecmascript/patch/patch_loader.h" 32 #include "ecmascript/stackmap/ark_stackmap.h" 33 #include "ecmascript/waiter_list.h" 34 #include "global_handle_collection.h" 35 #include "libpandafile/file.h" 36 37 namespace panda { 38 class JSNApi; 39 namespace panda_file { 40 class File; 41 } // namespace panda_file 42 43 namespace ecmascript { 44 class AotConstantpoolPatcher; 45 class GlobalEnv; 46 class ObjectFactory; 47 class EcmaRuntimeStat; 48 class RegExpParserCache; 49 class JSPandaFileManager; 50 class JSPandaFile; 51 class ConstantPool; 52 class JSPromise; 53 class RegExpExecResultCache; 54 class EcmaHandleScope; 55 class SustainingJSHandleList; 56 class SustainingJSHandle; 57 enum class PromiseRejectionEvent : uint8_t; 58 59 template<typename T> 60 class JSHandle; 61 class JSThread; 62 class JSFunction; 63 class JSPromise; 64 class JSTaggedValue; 65 class EcmaVM; 66 class ModuleManager; 67 class AOTFileManager; 68 class QuickFixManager; 69 class OptCodeProfiler; 70 class TypedOpProfiler; 71 class AbcBufferCache; 72 struct CJSInfo; 73 class FunctionProtoTransitionTable; 74 class ModuleLogger; 75 76 namespace job { 77 class MicroJobQueue; 78 } // namespace job 79 namespace tooling { 80 class JsDebuggerManager; 81 } // namespace tooling 82 namespace kungfu { 83 class PGOTypeManager; 84 } // namespace kungfu 85 86 using HostPromiseRejectionTracker = void (*)(const EcmaVM* vm, 87 const JSHandle<JSPromise> promise, 88 const JSHandle<JSTaggedValue> reason, 89 PromiseRejectionEvent operation, 90 void* data); 91 using PromiseRejectCallback = void (*)(void* info); 92 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) 93 using JsAotReaderCallback = std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)>; 94 #endif 95 class EcmaContext { 96 public: 97 enum JSErrorProps { 98 NAME, 99 MESSAGE, 100 STACK 101 }; 102 103 static EcmaContext *CreateAndInitialize(JSThread *thread); 104 static void CheckAndDestroy(JSThread *thread, EcmaContext *context); 105 106 static EcmaContext *Create(JSThread *thread); 107 static bool Destroy(EcmaContext *context); 108 109 EcmaContext(JSThread *thread); 110 ~EcmaContext(); 111 struct EcmaData 112 : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(), 113 base::AlignedPointer, 114 #if ECMASCRIPT_ENABLE_MEGA_PROFILER 115 base::AlignedPointer, 116 base::AlignedUint64, 117 base::AlignedUint64, 118 base::AlignedUint64> 119 #else 120 base::AlignedPointer> 121 #endif 122 { 123 enum class Index : size_t { 124 LoadMegaICCacheIndex, 125 StoreMegaICCacheIndex, 126 PropertiesCacheIndex, 127 #if ECMASCRIPT_ENABLE_MEGA_PROFILER 128 megaUpdateCountIndex, 129 megaProbesCountIndex, 130 megaHitCountIndex, 131 #endif 132 NumOfMembers 133 }; 134 #if ECMASCRIPT_ENABLE_MEGA_PROFILER 135 static_assert(static_cast<size_t>(Index::NumOfMembers) == 6); 136 #else 137 static_assert(static_cast<size_t>(Index::NumOfMembers) == 3); 138 #endif GetLoadMegaICCacheOffsetEcmaData139 static size_t GetLoadMegaICCacheOffset(bool isArch32) 140 { 141 return GetOffset<static_cast<size_t>(Index::LoadMegaICCacheIndex)>( 142 isArch32); 143 } 144 GetStoreMegaICCacheOffsetEcmaData145 static size_t GetStoreMegaICCacheOffset(bool isArch32) 146 { 147 return GetOffset<static_cast<size_t>(Index::StoreMegaICCacheIndex)>( 148 isArch32); 149 } 150 GetPropertiesCacheOffsetEcmaData151 static size_t GetPropertiesCacheOffset(bool isArch32) 152 { 153 return GetOffset<static_cast<size_t>(Index::PropertiesCacheIndex)>( 154 isArch32); 155 } 156 #if ECMASCRIPT_ENABLE_MEGA_PROFILER GetMegaProbesCountOffsetEcmaData157 static size_t GetMegaProbesCountOffset(bool isArch32) 158 { 159 return GetOffset<static_cast<size_t>(Index::megaProbesCountIndex)>( 160 isArch32); 161 } 162 GetMegaHitCountOffsetEcmaData163 static size_t GetMegaHitCountOffset(bool isArch32) 164 { 165 return GetOffset<static_cast<size_t>(Index::megaHitCountIndex)>( 166 isArch32); 167 } 168 #endif 169 alignas(EAS) MegaICCache *loadMegaICCache_{nullptr}; 170 alignas(EAS) MegaICCache *storeMegaICCache_{nullptr}; 171 alignas(EAS) PropertiesCache *propertiesCache_{nullptr}; 172 #if ECMASCRIPT_ENABLE_MEGA_PROFILER 173 alignas(EAS) uint64_t megaUpdateCount_ {0}; 174 alignas(EAS) uint64_t megaProbesCount_ {0}; 175 alignas(EAS) uint64_t megaHitCount {0}; 176 #endif 177 }; 178 GetEcmaVM()179 EcmaVM *GetEcmaVM() const 180 { 181 return vm_; 182 } 183 184 bool Initialize(); 185 IsExecutingPendingJob()186 bool IsExecutingPendingJob() const 187 { 188 return isProcessingPendingJob_.load(); 189 } 190 191 bool HasPendingJob(); 192 193 bool ExecutePromisePendingJob(); 194 ConstCast(const EcmaContext * context)195 static EcmaContext *ConstCast(const EcmaContext *context) 196 { 197 return const_cast<EcmaContext *>(context); 198 } 199 IsInitialized()200 bool IsInitialized() const 201 { 202 return initialized_; 203 } 204 GetModuleManager()205 ModuleManager *GetModuleManager() const 206 { 207 return moduleManager_; 208 } 209 GetAbcBufferCache()210 AbcBufferCache *GetAbcBufferCache() const 211 { 212 return abcBufferCache_; 213 } 214 GetPTManager()215 kungfu::PGOTypeManager *GetPTManager() const 216 { 217 return ptManager_; 218 } 219 GetJSThread()220 ARK_INLINE JSThread *GetJSThread() const 221 { 222 return thread_; 223 } GetPromiseRejectCallback()224 PromiseRejectCallback GetPromiseRejectCallback() const 225 { 226 return promiseRejectCallback_; 227 } 228 SetPromiseRejectCallback(PromiseRejectCallback cb)229 void SetPromiseRejectCallback(PromiseRejectCallback cb) 230 { 231 promiseRejectCallback_ = cb; 232 } 233 SetData(void * data)234 void SetData(void* data) 235 { 236 data_ = data; 237 } 238 PromiseRejectionTracker(const JSHandle<JSPromise> & promise,const JSHandle<JSTaggedValue> & reason,PromiseRejectionEvent operation)239 void PromiseRejectionTracker(const JSHandle<JSPromise> &promise, 240 const JSHandle<JSTaggedValue> &reason, PromiseRejectionEvent operation) 241 { 242 if (hostPromiseRejectionTracker_ != nullptr) { 243 hostPromiseRejectionTracker_(vm_, promise, reason, operation, data_); 244 } 245 } 246 SetHostPromiseRejectionTracker(HostPromiseRejectionTracker cb)247 void SetHostPromiseRejectionTracker(HostPromiseRejectionTracker cb) 248 { 249 hostPromiseRejectionTracker_ = cb; 250 } 251 void SetupRegExpResultCache(); 252 void SetupNumberToStringResultCache(); 253 void SetupStringSplitResultCache(); 254 void SetupStringToListResultCache(); GetRegExpCache()255 JSHandle<JSTaggedValue> GetRegExpCache() const 256 { 257 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(®expCache_)); 258 } 259 GetRegExpParserCache()260 RegExpParserCache *GetRegExpParserCache() const 261 { 262 ASSERT(regExpParserCache_ != nullptr); 263 return regExpParserCache_; 264 } 265 SetRegExpCache(JSTaggedValue newCache)266 void SetRegExpCache(JSTaggedValue newCache) 267 { 268 regexpCache_ = newCache; 269 } GetExpCacheAddress()270 uintptr_t GetExpCacheAddress() 271 { 272 return reinterpret_cast<uintptr_t>(®expCache_); 273 } 274 275 void SetupRegExpGlobalResult(); 276 GetRegExpGlobalResult()277 JSHandle<JSTaggedValue> GetRegExpGlobalResult() const 278 { 279 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(®expGlobal_)); 280 } 281 SetRegExpGlobalResult(JSTaggedValue newResult)282 void SetRegExpGlobalResult(JSTaggedValue newResult) 283 { 284 regexpGlobal_ = newResult; 285 } 286 GetWaiterListNode()287 WaiterListNode *GetWaiterListNode() 288 { 289 return &waiterListNode_; 290 } 291 GetNumberToStringResultCache()292 JSHandle<JSTaggedValue> GetNumberToStringResultCache() const 293 { 294 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&numberToStringResultCache_)); 295 } 296 SetNumberToStringResultCache(JSTaggedValue newCache)297 void SetNumberToStringResultCache(JSTaggedValue newCache) 298 { 299 numberToStringResultCache_ = newCache; 300 } 301 GetStringSplitResultCache()302 JSHandle<JSTaggedValue> GetStringSplitResultCache() const 303 { 304 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringSplitResultCache_)); 305 } 306 GetStringToListResultCache()307 JSHandle<JSTaggedValue> GetStringToListResultCache() const 308 { 309 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringToListResultCache_)); 310 } 311 SetStringSplitResultCache(JSTaggedValue newCache)312 void SetStringSplitResultCache(JSTaggedValue newCache) 313 { 314 stringSplitResultCache_ = newCache; 315 } 316 JSHandle<ecmascript::JSTaggedValue> GetAndClearEcmaUncaughtException() const; 317 JSHandle<ecmascript::JSTaggedValue> GetEcmaUncaughtException() const; 318 void EnableUserUncaughtErrorHandler(); 319 320 JSHandle<ConstantPool> AddOrUpdateConstpool(const JSPandaFile *jsPandaFile, 321 JSHandle<ConstantPool> constpool, 322 int32_t index = 0); 323 void AddContextConstpoolCache(const JSPandaFile *jsPandaFile, 324 JSHandle<ConstantPool> constpool, 325 int32_t index); 326 327 void UpdateConstpoolWhenDeserialAI(const std::string& fileName, 328 JSHandle<ConstantPool> aiCP, 329 int32_t index = 0); 330 331 bool HasCachedConstpool(const JSPandaFile *jsPandaFile) const; 332 333 void SetUnsharedConstpool(JSHandle<ConstantPool> sharedConstpool, JSTaggedValue unsharedConstpool); 334 void SetUnsharedConstpool(int32_t constpoolIndex, JSTaggedValue unsharedConstpool); 335 336 JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, int32_t index); 337 // For new version instruction. 338 JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id); 339 JSTaggedValue PUBLIC_API FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool); 340 JSTaggedValue PUBLIC_API FindUnsharedConstpool(JSTaggedValue sharedConstpool); 341 void PUBLIC_API LoadProtoTransitionTable(JSTaggedValue constpool); 342 void PUBLIC_API ResetProtoTransitionTableOnConstpool(JSTaggedValue constpool); 343 JSTaggedValue FindCachedConstpoolAndLoadAiIfNeeded(const JSPandaFile *jsPandaFile, int32_t index); 344 void EraseUnusedConstpool(const JSPandaFile *jsPandaFile, int32_t index, int32_t constpoolIndex); 345 std::optional<std::reference_wrapper<CMap<int32_t, JSTaggedValue>>> FindConstpools( 346 const JSPandaFile *jsPandaFile); 347 348 JSHandle<ConstantPool> PUBLIC_API FindOrCreateConstPool(const JSPandaFile *jsPandaFile, 349 panda_file::File::EntityId id); 350 void SetPrototypeForTransitions(JSTaggedValue trans, JSTaggedValue proto); 351 void SetObjectFunctionFromConstPool(JSHandle<ConstantPool> newConstPool); 352 void CreateAllConstpool(const JSPandaFile *jsPandaFile); 353 354 void HandleUncaughtException(JSTaggedValue exception); 355 void HandleUncaughtException(); 356 JSHandle<GlobalEnv> GetGlobalEnv() const; GlobalEnvIsHole()357 bool GlobalEnvIsHole() 358 { 359 return globalEnv_.IsHole(); 360 } 361 362 JSHandle<job::MicroJobQueue> GetMicroJobQueue() const; 363 364 static void PrintJSErrorInfo(JSThread *thread, const JSHandle<JSTaggedValue> &exceptionInfo); 365 static CString GetJSErrorInfo(JSThread *thread, const JSHandle<JSTaggedValue> exceptionInfo, JSErrorProps key); 366 void IterateMegaIC(RootVisitor &v); 367 void Iterate(RootVisitor &v); 368 static void MountContext(JSThread *thread); 369 static void UnmountContext(JSThread *thread); 370 void SetMicroJobQueue(job::MicroJobQueue *queue); 371 void SetGlobalEnv(GlobalEnv *global); 372 void PrintOptStat(); 373 GetOptCodeProfiler()374 OptCodeProfiler *GetOptCodeProfiler() const 375 { 376 return optCodeProfiler_; 377 } 378 GetTypdOpProfiler()379 TypedOpProfiler *GetTypdOpProfiler() const 380 { 381 return typedOpProfiler_; 382 } 383 GetModuleLogger()384 ModuleLogger *GetModuleLogger() const 385 { 386 return moduleLogger_; 387 } 388 SetModuleLogger(ModuleLogger * moduleLogger)389 void SetModuleLogger(ModuleLogger *moduleLogger) 390 { 391 moduleLogger_ = moduleLogger; 392 } 393 GetFunctionProtoTransitionTable()394 FunctionProtoTransitionTable *GetFunctionProtoTransitionTable() const 395 { 396 return functionProtoTransitionTable_; 397 } 398 399 void DumpAOTInfo() const DUMP_API_ATTR; 400 401 JSTaggedValue ExecuteAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp, 402 bool needPushArgv); 403 void LoadStubFile(); 404 GetHandleScopeStorageNext()405 JSTaggedType *GetHandleScopeStorageNext() const 406 { 407 return handleScopeStorageNext_; 408 } 409 SetHandleScopeStorageNext(JSTaggedType * value)410 void SetHandleScopeStorageNext(JSTaggedType *value) 411 { 412 handleScopeStorageNext_ = value; 413 } 414 GetHandleScopeStorageEnd()415 JSTaggedType *GetHandleScopeStorageEnd() const 416 { 417 return handleScopeStorageEnd_; 418 } 419 SetHandleScopeStorageEnd(JSTaggedType * value)420 void SetHandleScopeStorageEnd(JSTaggedType *value) 421 { 422 handleScopeStorageEnd_ = value; 423 } 424 GetCurrentHandleStorageIndex()425 int GetCurrentHandleStorageIndex() const 426 { 427 return currentHandleStorageIndex_; 428 } 429 GetPrimitiveScopeStorageNext()430 JSTaggedType *GetPrimitiveScopeStorageNext() const 431 { 432 return primitiveScopeStorageNext_; 433 } 434 SetPrimitiveScopeStorageNext(JSTaggedType * value)435 void SetPrimitiveScopeStorageNext(JSTaggedType *value) 436 { 437 primitiveScopeStorageNext_ = value; 438 } 439 GetPrimitiveScopeStorageEnd()440 JSTaggedType *GetPrimitiveScopeStorageEnd() const 441 { 442 return primitiveScopeStorageEnd_; 443 } 444 SetPrimitiveScopeStorageEnd(JSTaggedType * value)445 void SetPrimitiveScopeStorageEnd(JSTaggedType *value) 446 { 447 primitiveScopeStorageEnd_ = value; 448 } 449 GetCurrentPrimitiveStorageIndex()450 int GetCurrentPrimitiveStorageIndex() const 451 { 452 return currentPrimitiveStorageIndex_; 453 } 454 455 size_t IterateHandle(RootVisitor &visitor); 456 uintptr_t *ExpandHandleStorage(); 457 void ShrinkHandleStorage(int prevIndex); 458 uintptr_t *ExpandPrimitiveStorage(); 459 void ShrinkPrimitiveStorage(int prevIndex); 460 GetPropertiesCache()461 PropertiesCache *GetPropertiesCache() const 462 { 463 return ecmaData_.propertiesCache_; 464 } 465 GetLoadMegaICCache()466 MegaICCache *GetLoadMegaICCache() const 467 { 468 return ecmaData_.loadMegaICCache_; 469 } 470 GetStoreMegaICCache()471 MegaICCache *GetStoreMegaICCache() const 472 { 473 return ecmaData_.storeMegaICCache_; 474 } 475 #if ECMASCRIPT_ENABLE_MEGA_PROFILER GetMegaProbeCount()476 uint64_t GetMegaProbeCount() const 477 { 478 return ecmaData_.megaProbesCount_; 479 } 480 GetMegaHitCount()481 uint64_t GetMegaHitCount() const 482 { 483 return ecmaData_.megaHitCount; 484 } 485 GetMegaUpdateCount()486 uint64_t GetMegaUpdateCount() const 487 { 488 return ecmaData_.megaUpdateCount_; 489 } 490 IncMegaUpdateCount()491 void IncMegaUpdateCount() 492 { 493 ecmaData_.megaUpdateCount_++; 494 } 495 ClearMegaStat()496 void ClearMegaStat() 497 { 498 ecmaData_.megaHitCount = 0; 499 ecmaData_.megaProbesCount_ = 0; 500 ecmaData_.megaUpdateCount_ = 0; 501 } PrintMegaICStat()502 void PrintMegaICStat() 503 { 504 const int precision = 2; 505 const double percent = 100.0; 506 LOG_ECMA(INFO) 507 << "------------------------------------------------------------" 508 << "---------------------------------------------------------"; 509 LOG_ECMA(INFO) << "MegaUpdateCount: " << GetMegaUpdateCount(); 510 LOG_ECMA(INFO) << "MegaHitCount: " << GetMegaHitCount(); 511 LOG_ECMA(INFO) << "MegaProbeCount: " << GetMegaProbeCount(); 512 LOG_ECMA(INFO) << "MegaHitRate: " << std::fixed 513 << std::setprecision(precision) 514 << (GetMegaProbeCount() > 0 515 ? static_cast<double>(GetMegaHitCount()) / 516 GetMegaProbeCount() * percent 517 : 0.0) 518 << "%"; 519 LOG_ECMA(INFO) 520 << "------------------------------------------------------------" 521 << "---------------------------------------------------------"; 522 ClearMegaStat(); 523 } 524 #endif 525 void ClearBufferData(); GlobalConstants()526 const GlobalEnvConstants *GlobalConstants() const 527 { 528 return &globalConst_; 529 } 530 AddPatchModule(const CString & recordName,const JSHandle<JSTaggedValue> moduleRecord)531 void AddPatchModule(const CString &recordName, const JSHandle<JSTaggedValue> moduleRecord) 532 { 533 cachedPatchModules_.emplace(recordName, moduleRecord); 534 } FindPatchModule(const CString & recordName)535 JSHandle<JSTaggedValue> FindPatchModule(const CString &recordName) const 536 { 537 auto iter = cachedPatchModules_.find(recordName); 538 if (iter != cachedPatchModules_.end()) { 539 return iter->second; 540 } 541 return JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Hole()); 542 } ClearPatchModules()543 void ClearPatchModules() 544 { 545 GlobalHandleCollection gloalHandleCollection(thread_); 546 for (auto &item : cachedPatchModules_) { 547 gloalHandleCollection.Dispose(item.second); 548 } 549 cachedPatchModules_.clear(); 550 } 551 GetStageOfHotReload()552 StageOfHotReload GetStageOfHotReload() const 553 { 554 return stageOfHotReload_; 555 } SetStageOfHotReload(StageOfHotReload stageOfHotReload)556 void SetStageOfHotReload(StageOfHotReload stageOfHotReload) 557 { 558 stageOfHotReload_ = stageOfHotReload; 559 } 560 GetStageOfColdReload()561 StageOfColdReload GetStageOfColdReload() const 562 { 563 return stageOfColdReload_; 564 } SetStageOfColdReload(StageOfColdReload stageOfColdReload)565 void SetStageOfColdReload(StageOfColdReload stageOfColdReload) 566 { 567 stageOfColdReload_ = stageOfColdReload; 568 } 569 570 bool JoinStackPushFastPath(JSHandle<JSTaggedValue> receiver); 571 bool JoinStackPush(JSHandle<JSTaggedValue> receiver); 572 void JoinStackPopFastPath(JSHandle<JSTaggedValue> receiver); 573 void JoinStackPop(JSHandle<JSTaggedValue> receiver); 574 575 std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr, 576 bool isDeopt) const; 577 578 void AddSustainingJSHandle(SustainingJSHandle*); 579 void RemoveSustainingJSHandle(SustainingJSHandle*); 580 void ClearKeptObjects(); 581 void AddToKeptObjects(JSHandle<JSTaggedValue> value); 582 ClearCachedConstantPool()583 void ClearCachedConstantPool() 584 { 585 cachedSharedConstpools_.clear(); 586 } 587 588 private: 589 void CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg, 590 const JSPandaFile *jsPandaFile, std::string_view entryPoint); 591 JSTaggedValue InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSHandle<JSTaggedValue> &thisArg, 592 const JSPandaFile *jsPandaFile, std::string_view entryPoint, 593 CJSInfo *cjsInfo = nullptr); 594 Expected<JSTaggedValue, bool> InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, std::string_view entryPoint, 595 const ExecuteTypes &executeType = ExecuteTypes::STATIC); 596 Expected<JSTaggedValue, bool> InvokeEcmaEntrypointForHotReload( 597 const JSPandaFile *jsPandaFile, std::string_view entryPoint, const ExecuteTypes &executeType); 598 Expected<JSTaggedValue, bool> CommonInvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, 599 std::string_view entryPoint, JSHandle<JSFunction> &func, const ExecuteTypes &executeType); 600 bool LoadAOTFilesInternal(const std::string& aotFileName); 601 bool LoadAOTFiles(const std::string &aotFileName); 602 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) 603 bool LoadAOTFiles(const std::string &aotFileName, 604 std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)> cb); 605 #endif 606 void RelocateConstantString(const JSPandaFile *jsPandaFile); 607 JSTaggedValue FindConstpoolFromContextCache(const JSPandaFile *jsPandaFile, int32_t index); 608 609 void GrowUnsharedConstpoolArray(int32_t index); 610 void ResizeUnsharedConstpoolArray(int32_t oldCapacity, int32_t minCapacity); ClearUnsharedConstpoolArray()611 void ClearUnsharedConstpoolArray() 612 { 613 if (unsharedConstpools_ != nullptr) { 614 delete[] unsharedConstpools_; 615 unsharedConstpools_ = nullptr; 616 thread_->SetUnsharedConstpools(reinterpret_cast<uintptr_t>(nullptr)); 617 thread_->SetUnsharedConstpoolsArrayLen(0); 618 } 619 } 620 GetUnsharedConstpoolsArrayLen()621 int32_t GetUnsharedConstpoolsArrayLen() const 622 { 623 return unsharedConstpoolsArrayLen_; 624 } 625 SetUnsharedConstpoolsArrayLen(int32_t len)626 void SetUnsharedConstpoolsArrayLen(int32_t len) 627 { 628 unsharedConstpoolsArrayLen_ = len; 629 } 630 631 NO_MOVE_SEMANTIC(EcmaContext); 632 NO_COPY_SEMANTIC(EcmaContext); 633 EcmaData ecmaData_; 634 JSThread *thread_{nullptr}; 635 EcmaVM *vm_{nullptr}; 636 637 bool isUncaughtExceptionRegistered_ {false}; 638 bool initialized_ {false}; 639 std::atomic<bool> isProcessingPendingJob_ {false}; 640 ObjectFactory *factory_ {nullptr}; 641 642 // VM execution states. 643 RegExpParserCache *regExpParserCache_ {nullptr}; 644 JSTaggedValue numberToStringResultCache_ {JSTaggedValue::Hole()}; 645 JSTaggedValue stringSplitResultCache_ {JSTaggedValue::Hole()}; 646 JSTaggedValue stringToListResultCache_ {JSTaggedValue::Hole()}; 647 JSTaggedValue globalEnv_ {JSTaggedValue::Hole()}; 648 JSTaggedValue regexpCache_ {JSTaggedValue::Hole()}; 649 JSTaggedValue regexpGlobal_ {JSTaggedValue::Hole()}; 650 JSTaggedValue microJobQueue_ {JSTaggedValue::Hole()}; 651 652 CMap<const JSPandaFile *, CMap<int32_t, JSTaggedValue>> cachedSharedConstpools_ {}; 653 JSTaggedValue* unsharedConstpools_ = nullptr; 654 int32_t unsharedConstpoolsArrayLen_ = UNSHARED_CONSTANTPOOL_COUNT; 655 static constexpr int32_t SHARED_CONSTPOOL_KEY_NOT_FOUND = INT32_MAX; // INT32_MAX :invalid value. 656 657 // for HotReload of module. 658 CMap<CString, JSHandle<JSTaggedValue>> cachedPatchModules_ {}; 659 StageOfHotReload stageOfHotReload_ = StageOfHotReload::INITIALIZE_STAGE_OF_HOTRELOAD; 660 StageOfColdReload stageOfColdReload_ = StageOfColdReload::NOT_COLD_RELOAD; 661 662 // VM resources. 663 ModuleManager *moduleManager_ {nullptr}; 664 kungfu::PGOTypeManager *ptManager_ {nullptr}; 665 AOTFileManager *aotFileManager_ {nullptr}; 666 AbcBufferCache *abcBufferCache_ {nullptr}; 667 668 // for recording the transition of function prototype 669 FunctionProtoTransitionTable *functionProtoTransitionTable_ {nullptr}; 670 671 // atomics 672 WaiterListNode waiterListNode_; 673 674 // Registered Callbacks 675 PromiseRejectCallback promiseRejectCallback_ {nullptr}; 676 HostPromiseRejectionTracker hostPromiseRejectionTracker_ {nullptr}; 677 void* data_{nullptr}; 678 679 // opt code Profiler 680 OptCodeProfiler *optCodeProfiler_ {nullptr}; 681 682 // opt code loop hoist 683 TypedOpProfiler *typedOpProfiler_ {nullptr}; 684 685 ModuleLogger *moduleLogger_ {nullptr}; 686 687 // Handlescope 688 static const uint32_t NODE_BLOCK_SIZE_LOG2 = 10; 689 static const uint32_t NODE_BLOCK_SIZE = 1U << NODE_BLOCK_SIZE_LOG2; 690 static constexpr int32_t MIN_HANDLE_STORAGE_SIZE = 2; 691 JSTaggedType *handleScopeStorageNext_ {nullptr}; 692 JSTaggedType *handleScopeStorageEnd_ {nullptr}; 693 std::vector<std::array<JSTaggedType, NODE_BLOCK_SIZE> *> handleStorageNodes_ {}; 694 int32_t currentHandleStorageIndex_ {-1}; 695 // PrimitveScope 696 static constexpr int32_t MIN_PRIMITIVE_STORAGE_SIZE = 2; 697 JSTaggedType *primitiveScopeStorageNext_ {nullptr}; 698 JSTaggedType *primitiveScopeStorageEnd_ {nullptr}; 699 std::vector<std::array<JSTaggedType, NODE_BLOCK_SIZE> *> primitiveStorageNodes_ {}; 700 int32_t currentPrimitiveStorageIndex_ {-1}; 701 702 GlobalEnvConstants globalConst_; 703 // Join Stack 704 static constexpr uint32_t MIN_JOIN_STACK_SIZE = 2; 705 CVector<JSTaggedValue> joinStack_ {JSTaggedValue::Hole(), JSTaggedValue::Hole()}; 706 707 // SustainingJSHandleList for jit compile hold ref 708 SustainingJSHandleList *sustainingJSHandleList_ {nullptr}; 709 710 friend class EcmaHandleScope; 711 friend class JSPandaFileExecutor; 712 friend class ObjectFactory; 713 friend class panda::JSNApi; 714 friend class AOTFileManager; 715 }; 716 } // namespace ecmascript 717 } // namespace panda 718 #endif // ECMASCRIPT_ECMA_CONTEXT_H 719