diff --git a/ecmascript/class_linker/panda_file_translator.cpp b/ecmascript/class_linker/panda_file_translator.cpp index 7d5bf61462..9e75c43d36 100644 --- a/ecmascript/class_linker/panda_file_translator.cpp +++ b/ecmascript/class_linker/panda_file_translator.cpp @@ -47,16 +47,6 @@ PandaFileTranslator::PandaFileTranslator(EcmaVM *vm, const JSPandaFile *jsPandaF { } -void PandaFileTranslator::TranslateAndCollectPandaFile(const CString &methodName, - std::vector *infoList) -{ - if (ecmaVm_->GetJSOptions().IsEnableTsAot()) { - TSLoader *tsLoader = ecmaVm_->GetTSLoader(); - tsLoader->DecodeTSTypes(*jsPandaFile_->GetPandaFile()); - } - TranslateClasses(const_cast(jsPandaFile_), methodName, infoList); -} - template static T *InitializeMemory(T *mem, Args... args) { @@ -244,7 +234,6 @@ Program *PandaFileTranslator::GenerateProgram() JSHandle jsPandaFilePointer = factory_->NewJSNativePointer( const_cast(jsPandaFile_), JSPandaFileManager::RemoveJSPandaFile, EcmaVM::GetJSPandaFileManager()); - ecmaVm_->PushToArrayDataList(*jsPandaFilePointer); constpool->Set(thread_, constpoolIndex, jsPandaFilePointer.GetTaggedValue()); } diff --git a/ecmascript/compiler/pass_manager.cpp b/ecmascript/compiler/pass_manager.cpp index faa7d4e2a7..873a3bd8a0 100644 --- a/ecmascript/compiler/pass_manager.cpp +++ b/ecmascript/compiler/pass_manager.cpp @@ -20,8 +20,7 @@ namespace panda::ecmascript::kungfu { bool PassManager::Compile(std::string fileName) { std::vector infoList; - const panda_file::File *file = nullptr; - auto res = vm_->CollectInfoOfPandaFile(fileName, entry_, &infoList, file); + auto res = vm_->CollectInfoOfPandaFile(fileName, &infoList); if (!res) { std::cerr << "Cannot execute panda file '" << fileName << "' with entry '" << entry_ << "'" << std::endl; return false; diff --git a/ecmascript/ecma_vm.cpp b/ecmascript/ecma_vm.cpp index c0027c2e1c..6b299c434c 100644 --- a/ecmascript/ecma_vm.cpp +++ b/ecmascript/ecma_vm.cpp @@ -113,7 +113,6 @@ Expected EcmaVM::Create(Runtime *runtime) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) EcmaVM::EcmaVM() : EcmaVM(EcmaVM::GetJSOptions()) { - isTestMode_ = true; } EcmaVM::EcmaVM(JSRuntimeOptions options) @@ -121,8 +120,7 @@ EcmaVM::EcmaVM(JSRuntimeOptions options) nativeAreaAllocator_(std::make_unique()), heapRegionAllocator_(std::make_unique()), chunk_(nativeAreaAllocator_.get()), - arrayBufferDataList_(&chunk_), - frameworkProgramMethods_(&chunk_), + nativePointerList_(&chunk_), nativeMethods_(&chunk_) { options_ = std::move(options); @@ -201,9 +199,10 @@ bool EcmaVM::Initialize() #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT) LOG_ECMA(DEBUG) << "EcmaVM::Initialize run snapshot"; SnapShot snapShot(this); - std::unique_ptr pf = snapShot.DeserializeGlobalEnvAndProgram(snapshotFileName_); - frameworkPandaFile_ = GetJSPandaFileManager()->CreateJSPandaFile(pf.release(), frameworkAbcFileName_); + frameworkPandaFile_ = snapShot.DeserializeGlobalEnvAndProgram(snapshotFileName_, frameworkAbcFileName_); globalConst->InitGlobalUndefined(); +#else + LOG_ECMA(FATAL) << "Don't support snapshot now."; #endif } @@ -335,54 +334,40 @@ EcmaVM::~EcmaVM() delete thread_; thread_ = nullptr; } - - frameworkProgramMethods_.clear(); } bool EcmaVM::ExecuteFromPf(const std::string &filename, std::string_view entryPoint, const std::vector &args, bool isModule) { - const JSPandaFile *jsPandaFile = nullptr; - if (frameworkPandaFile_ == nullptr || !IsFrameworkPandaFile(filename)) { - jsPandaFile = GetJSPandaFileManager()->LoadPfAbc(filename); - if (jsPandaFile == nullptr) { - return false; - } - } else { - jsPandaFile = frameworkPandaFile_; + const JSPandaFile *jsPandaFile = GetJSPandaFileManager()->LoadJSPandaFile(filename); + if (jsPandaFile == nullptr) { + return false; } + return Execute(jsPandaFile, entryPoint, args); } -bool EcmaVM::CollectInfoOfPandaFile(const std::string &filename, std::string_view entryPoint, - std::vector *infoList, const panda_file::File *&pf) +bool EcmaVM::CollectInfoOfPandaFile(const std::string &filename, std::vector *infoList) { - const JSPandaFile *jsPandaFile; - if (frameworkPandaFile_ == nullptr || !IsFrameworkPandaFile(filename)) { - jsPandaFile = GetJSPandaFileManager()->LoadPfAbc(filename); - if (jsPandaFile == nullptr) { - return false; - } - } else { - jsPandaFile = frameworkPandaFile_; - } - - // Get ClassName and MethodName - size_t pos = entryPoint.find_last_of("::"); - if (pos == std::string_view::npos) { - LOG_ECMA(ERROR) << "EntryPoint:" << entryPoint << " is illegal"; + const JSPandaFile *jsPandaFile = GetJSPandaFileManager()->LoadAotInfoFromPf(filename, infoList); + if (jsPandaFile == nullptr) { return false; } - CString methodName(entryPoint.substr(pos + 1)); - PandaFileTranslator translator(this, jsPandaFile); - translator.TranslateAndCollectPandaFile(methodName, infoList); + if (GetJSOptions().IsEnableTsAot()) { + TSLoader *tsLoader = GetTSLoader(); + tsLoader->DecodeTSTypes(*jsPandaFile->GetPandaFile()); + } return true; } bool EcmaVM::ExecuteFromBuffer(const void *buffer, size_t size, std::string_view entryPoint, const std::vector &args, const std::string &filename) { + const JSPandaFile *jsPandaFile = GetJSPandaFileManager()->LoadJSPandaFile(filename, buffer, size); + if (jsPandaFile == nullptr) { + return false; + } // Get ClassName and MethodName size_t pos = entryPoint.find_last_of("::"); if (pos == std::string_view::npos) { @@ -390,10 +375,6 @@ bool EcmaVM::ExecuteFromBuffer(const void *buffer, size_t size, std::string_view return false; } CString methodName(entryPoint.substr(pos + 1)); - const JSPandaFile *jsPandaFile = GetJSPandaFileManager()->LoadBufferAbc(filename, buffer, size); - if (jsPandaFile == nullptr) { - return false; - } InvokeEcmaEntrypoint(jsPandaFile, methodName, args); return true; } @@ -443,22 +424,6 @@ JSMethod *EcmaVM::GetMethodForNativeFunction(const void *func) return nativeMethods_.back(); } -void EcmaVM::RedirectMethod(const panda_file::File &pf) -{ - for (auto method : frameworkProgramMethods_) { - method->SetPandaFile(&pf); - } -} - -Expected EcmaVM::InvokeEntrypointImpl(Method *entrypoint, const std::vector &args) -{ - // For testcase startup - const panda_file::File *file = entrypoint->GetPandaFile(); - const JSPandaFile *jsPandaFile = GetJSPandaFileManager()->GetJSPandaFile(file); - ASSERT(jsPandaFile != nullptr); - return InvokeEcmaEntrypoint(jsPandaFile, utf::Mutf8AsCString(entrypoint->GetName().data), args); -} - Expected EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, [[maybe_unused]] const CString &methodName, const std::vector &args) @@ -466,14 +431,16 @@ Expected EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *js [[maybe_unused]] EcmaHandleScope scope(thread_); JSHandle program; if (snapshotSerializeEnable_) { +#if defined(ECMASCRIPT_SUPPORT_SNAPSHOT) program = GetJSPandaFileManager()->GenerateProgram(this, jsPandaFile); auto index = jsPandaFile->GetJSPandaFileDesc().find(frameworkAbcFileName_); if (index != CString::npos) { -#if defined(ECMASCRIPT_SUPPORT_SNAPSHOT) LOG_ECMA(DEBUG) << "snapShot MakeSnapShotProgramObject abc " << jsPandaFile->GetJSPandaFileDesc(); SnapShot snapShot(this); snapShot.MakeSnapShotProgramObject(*program, jsPandaFile->GetPandaFile(), snapshotFileName_); +#else + LOG_ECMA(FATAL) << "Don't support snapshot now."; #endif } } else { @@ -481,7 +448,7 @@ Expected EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *js program = GetJSPandaFileManager()->GenerateProgram(this, jsPandaFile); } else { program = JSHandle(thread_, frameworkProgram_); - RedirectMethod(*jsPandaFile->GetPandaFile()); + frameworkProgram_ = JSTaggedValue::Hole(); } } if (program.IsEmpty()) { @@ -526,12 +493,6 @@ Expected EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *js return 0; } -bool EcmaVM::IsFrameworkPandaFile(std::string_view filename) const -{ - return filename.size() >= frameworkAbcFileName_.size() && - filename.substr(filename.size() - frameworkAbcFileName_.size()) == frameworkAbcFileName_; -} - JSHandle EcmaVM::GetAndClearEcmaUncaughtException() const { JSHandle exceptionHandle = GetEcmaUncaughtException(); @@ -593,12 +554,12 @@ void EcmaVM::ProcessReferences(const WeakRootVisitor &v0) } // array buffer - for (auto iter = arrayBufferDataList_.begin(); iter != arrayBufferDataList_.end();) { + for (auto iter = nativePointerList_.begin(); iter != nativePointerList_.end();) { JSNativePointer *object = *iter; auto fwd = v0(reinterpret_cast(object)); if (fwd == nullptr) { object->Destroy(); - iter = arrayBufferDataList_.erase(iter); + iter = nativePointerList_.erase(iter); } else if (fwd != reinterpret_cast(object)) { *iter = JSNativePointer::Cast(fwd); ++iter; @@ -606,31 +567,21 @@ void EcmaVM::ProcessReferences(const WeakRootVisitor &v0) ++iter; } } - - // framework program - if (!frameworkProgram_.IsHole()) { - auto fwd = v0(frameworkProgram_.GetTaggedObject()); - if (fwd == nullptr) { - frameworkProgram_ = JSTaggedValue::Undefined(); - } else if (fwd != frameworkProgram_.GetTaggedObject()) { - frameworkProgram_ = JSTaggedValue(fwd); - } - } } -void EcmaVM::PushToArrayDataList(JSNativePointer *array) +void EcmaVM::PushToNativePointerList(JSNativePointer *array) { - if (std::find(arrayBufferDataList_.begin(), arrayBufferDataList_.end(), array) != arrayBufferDataList_.end()) { + if (std::find(nativePointerList_.begin(), nativePointerList_.end(), array) != nativePointerList_.end()) { return; } - arrayBufferDataList_.emplace_back(array); + nativePointerList_.emplace_back(array); } -void EcmaVM::RemoveArrayDataList(JSNativePointer *array) +void EcmaVM::RemoveFromNativePointerList(JSNativePointer *array) { - auto iter = std::find(arrayBufferDataList_.begin(), arrayBufferDataList_.end(), array); - if (iter != arrayBufferDataList_.end()) { - arrayBufferDataList_.erase(iter); + auto iter = std::find(nativePointerList_.begin(), nativePointerList_.end(), array); + if (iter != nativePointerList_.end()) { + nativePointerList_.erase(iter); } } @@ -660,15 +611,10 @@ bool EcmaVM::VerifyFilePath(const CString &filePath) const void EcmaVM::ClearBufferData() { - for (auto iter : arrayBufferDataList_) { + for (auto iter : nativePointerList_) { iter->Destroy(); } - arrayBufferDataList_.clear(); - - if (frameworkPandaFile_) { - delete frameworkPandaFile_; - frameworkPandaFile_ = nullptr; - } + nativePointerList_.clear(); } bool EcmaVM::ExecutePromisePendingJob() const @@ -700,6 +646,7 @@ void EcmaVM::Iterate(const RootVisitor &v) v(Root::ROOT_VM, ObjectSlot(reinterpret_cast(&globalEnv_))); v(Root::ROOT_VM, ObjectSlot(reinterpret_cast(µJobQueue_))); v(Root::ROOT_VM, ObjectSlot(reinterpret_cast(®expCache_))); + v(Root::ROOT_VM, ObjectSlot(reinterpret_cast(&frameworkProgram_))); moduleManager_->Iterate(v); tsLoader_->Iterate(v); } diff --git a/ecmascript/ecma_vm.h b/ecmascript/ecma_vm.h index ec0e3a6184..2f0c951c21 100644 --- a/ecmascript/ecma_vm.h +++ b/ecmascript/ecma_vm.h @@ -107,9 +107,8 @@ public: bool ExecuteFromBuffer(const void *buffer, size_t size, std::string_view entryPoint, const std::vector &args, const std::string &filename = ""); - bool PUBLIC_API CollectInfoOfPandaFile(const std::string &filename, std::string_view entryPoint, - std::vector *infoList, - const panda_file::File *&pf); + bool PUBLIC_API CollectInfoOfPandaFile(const std::string &filename, + std::vector *infoList); PtJSExtractor *GetDebugInfoExtractor(const panda_file::File *file); @@ -277,8 +276,8 @@ public: return icEnable_; } - void PushToArrayDataList(JSNativePointer *array); - void RemoveArrayDataList(JSNativePointer *array); + void PushToNativePointerList(JSNativePointer *array); + void RemoveFromNativePointerList(JSNativePointer *array); JSHandle GetAndClearEcmaUncaughtException() const; JSHandle GetEcmaUncaughtException() const; @@ -404,15 +403,17 @@ protected: } Expected InvokeEntrypointImpl(Method *entrypoint, - const std::vector &args) override; + const std::vector &args) override + { + // unused interface + UNREACHABLE(); + } void HandleUncaughtException(ObjectHeader *exception) override; void PrintJSErrorInfo(const JSHandle &exceptionInfo); private: - bool IsFrameworkPandaFile(std::string_view filename) const; - void SetGlobalEnv(GlobalEnv *global); void SetMicroJobQueue(job::MicroJobQueue *queue); @@ -424,8 +425,6 @@ private: void InitializeEcmaScriptRunStat(); - void RedirectMethod(const panda_file::File &pf); - bool VerifyFilePath(const CString &filePath) const; void ClearBufferData(); @@ -437,7 +436,6 @@ private: // Useless/deprecated fields in the future: Rendezvous *rendezvous_{nullptr}; - bool isTestMode_ {false}; // VM startup states. static JSRuntimeOptions options_; @@ -455,7 +453,7 @@ private: Chunk chunk_; Heap *heap_ {nullptr}; ObjectFactory *factory_ {nullptr}; - ChunkVector arrayBufferDataList_; + ChunkVector nativePointerList_; // VM execution states. JSThread *thread_ {nullptr}; @@ -466,14 +464,13 @@ private: bool runtimeStatEnabled_ {false}; EcmaRuntimeStat *runtimeStat_ {nullptr}; - // App framework resources. - JSTaggedValue frameworkProgram_ {JSTaggedValue::Hole()}; + // For framewrok file snapshot. + CString snapshotFileName_; CString frameworkAbcFileName_; + JSTaggedValue frameworkProgram_ {JSTaggedValue::Hole()}; const JSPandaFile *frameworkPandaFile_ {nullptr}; - ChunkVector frameworkProgramMethods_; // VM resources. - CString snapshotFileName_; ChunkVector nativeMethods_; ModuleManager *moduleManager_ {nullptr}; TSLoader *tsLoader_ {nullptr}; diff --git a/ecmascript/js_arraybuffer.cpp b/ecmascript/js_arraybuffer.cpp index 8745db2b69..ee86dafb4a 100644 --- a/ecmascript/js_arraybuffer.cpp +++ b/ecmascript/js_arraybuffer.cpp @@ -41,7 +41,7 @@ void JSArrayBuffer::Attach(JSThread *thread, uint32_t arrayBufferByteLength, JST SetArrayBufferByteLength(arrayBufferByteLength); SetArrayBufferData(thread, arrayBufferData); EcmaVM *vm = thread->GetEcmaVM(); - vm->PushToArrayDataList(JSNativePointer::Cast(arrayBufferData.GetHeapObject())); + vm->PushToNativePointerList(JSNativePointer::Cast(arrayBufferData.GetHeapObject())); } void JSArrayBuffer::Detach(JSThread *thread) @@ -55,7 +55,7 @@ void JSArrayBuffer::Detach(JSThread *thread) EcmaVM *vm = thread->GetEcmaVM(); // remove vm's control over arrayBufferData. JSNativePointer *jsNativePointer = JSNativePointer::Cast(arrayBufferData.GetHeapObject()); - vm->RemoveArrayDataList(jsNativePointer); + vm->RemoveFromNativePointerList(jsNativePointer); jsNativePointer->Destroy(); SetArrayBufferData(thread, JSTaggedValue::Null()); diff --git a/ecmascript/js_collator.cpp b/ecmascript/js_collator.cpp index fe10e30d9d..17df369258 100644 --- a/ecmascript/js_collator.cpp +++ b/ecmascript/js_collator.cpp @@ -57,10 +57,8 @@ void JSCollator::SetIcuCollator(JSThread *thread, const JSHandle &co native->ResetExternalPointer(icuCollator); return; } - JSHandle pointer = factory->NewJSNativePointer(icuCollator); - pointer->SetDeleter(callback); + JSHandle pointer = factory->NewJSNativePointer(icuCollator, callback); collator->SetIcuField(thread, pointer.GetTaggedValue()); - ecmaVm->PushToArrayDataList(*pointer); } JSHandle JSCollator::InitializeCollator(JSThread *thread, const JSHandle &collator, diff --git a/ecmascript/js_date_time_format.cpp b/ecmascript/js_date_time_format.cpp index 72519c6a36..4f4d53e3b6 100644 --- a/ecmascript/js_date_time_format.cpp +++ b/ecmascript/js_date_time_format.cpp @@ -110,10 +110,8 @@ void JSDateTimeFormat::SetIcuLocale(JSThread *thread, JSHandle native->ResetExternalPointer(icuPointer); return; } - JSHandle pointer = factory->NewJSNativePointer(icuPointer); - pointer->SetDeleter(callback); + JSHandle pointer = factory->NewJSNativePointer(icuPointer, callback); obj->SetLocaleIcu(thread, pointer.GetTaggedValue()); - ecmaVm->PushToArrayDataList(*pointer); } void JSDateTimeFormat::FreeIcuLocale(void *pointer, void *data) @@ -150,10 +148,8 @@ void JSDateTimeFormat::SetIcuSimpleDateFormat(JSThread *thread, JSHandleResetExternalPointer(icuPointer); return; } - JSHandle pointer = factory->NewJSNativePointer(icuPointer); - pointer->SetDeleter(callback); + JSHandle pointer = factory->NewJSNativePointer(icuPointer, callback); obj->SetSimpleDateTimeFormatIcu(thread, pointer.GetTaggedValue()); - ecmaVm->PushToArrayDataList(*pointer); } void JSDateTimeFormat::FreeSimpleDateFormat(void *pointer, void *data) diff --git a/ecmascript/js_native_pointer.h b/ecmascript/js_native_pointer.h index 5d89aa9e7f..f793b41825 100644 --- a/ecmascript/js_native_pointer.h +++ b/ecmascript/js_native_pointer.h @@ -55,11 +55,9 @@ private: inline void DeleteExternalPointer() { void *externalPointer = GetExternalPointer(); - if (externalPointer != nullptr) { - DeleteEntryPoint deleter = GetDeleter(); - if (deleter != nullptr) { - deleter(externalPointer, GetData()); - } + DeleteEntryPoint deleter = GetDeleter(); + if (deleter != nullptr) { + deleter(externalPointer, GetData()); } } }; diff --git a/ecmascript/js_object.cpp b/ecmascript/js_object.cpp index 973f8616d2..e7841db325 100644 --- a/ecmascript/js_object.cpp +++ b/ecmascript/js_object.cpp @@ -1915,14 +1915,11 @@ void ECMAObject::SetNativePointerField(int32_t index, void *nativePointer, JSHandle current = JSHandle(thread, array->Get(thread, index + 1)); if (!current->IsHole() && nativePointer == nullptr) { // Try to remove native pointer if exists. - vm->RemoveArrayDataList(*JSHandle(current)); + vm->RemoveFromNativePointerList(*JSHandle(current)); array->Set(thread, index + 1, JSTaggedValue::Hole()); } else { JSHandle pointer = vm->GetFactory()->NewJSNativePointer( nativePointer, callBack, data); - if (callBack != nullptr) { - vm->PushToArrayDataList(*pointer); - } array->Set(thread, index + 1, pointer.GetTaggedValue()); } } diff --git a/ecmascript/js_plural_rules.cpp b/ecmascript/js_plural_rules.cpp index f7b7f8aee7..30b30e6219 100644 --- a/ecmascript/js_plural_rules.cpp +++ b/ecmascript/js_plural_rules.cpp @@ -54,10 +54,8 @@ void JSPluralRules::SetIcuNumberFormatter(JSThread *thread, const JSHandleResetExternalPointer(icuPointer); return; } - JSHandle pointer = factory->NewJSNativePointer(icuPointer); - pointer->SetDeleter(callback); + JSHandle pointer = factory->NewJSNativePointer(icuPointer, callback); pluralRules->SetIcuNF(thread, pointer.GetTaggedValue()); - ecmaVm->PushToArrayDataList(*pointer); } icu::PluralRules *JSPluralRules::GetIcuPluralRules() const @@ -91,10 +89,8 @@ void JSPluralRules::SetIcuPluralRules(JSThread *thread, const JSHandleResetExternalPointer(icuPointer); return; } - JSHandle pointer = factory->NewJSNativePointer(icuPointer); - pointer->SetDeleter(callback); + JSHandle pointer = factory->NewJSNativePointer(icuPointer, callback); pluralRules->SetIcuPR(thread, pointer.GetTaggedValue()); - ecmaVm->PushToArrayDataList(*pointer); } JSHandle JSPluralRules::BuildLocaleSet(JSThread *thread, const std::set &icuAvailableLocales) diff --git a/ecmascript/jspandafile/js_pandafile_manager.cpp b/ecmascript/jspandafile/js_pandafile_manager.cpp index 7b3c8f765f..23204c45e9 100644 --- a/ecmascript/jspandafile/js_pandafile_manager.cpp +++ b/ecmascript/jspandafile/js_pandafile_manager.cpp @@ -30,7 +30,20 @@ JSPandaFileManager::~JSPandaFileManager() } } -const JSPandaFile *JSPandaFileManager::LoadPfAbc(const std::string &filename) +// generate aot info on host +const JSPandaFile *JSPandaFileManager::LoadAotInfoFromPf(const std::string &filename, + std::vector *infoList) +{ + CString desc = ConvertToString(filename); + auto pf = panda_file::OpenPandaFileOrZip(filename, panda_file::File::READ_WRITE); + + JSPandaFile *jsPandaFile = NewJSPandaFile(pf.release(), desc); + PandaFileTranslator::TranslateClasses(jsPandaFile, ENTRY_FUNCTION_NAME, infoList); + + return jsPandaFile; +} + +const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(const std::string &filename) { CString desc = ConvertToString(filename); const JSPandaFile *jsPandaFile = FindJSPandaFile(desc); @@ -45,11 +58,11 @@ const JSPandaFile *JSPandaFileManager::LoadPfAbc(const std::string &filename) return nullptr; } - jsPandaFile = CreateJSPandaFile(pf.release(), desc); + jsPandaFile = GenerateJSPandaFile(pf.release(), desc); return jsPandaFile; } -const JSPandaFile *JSPandaFileManager::LoadBufferAbc(const std::string &filename, const void *buffer, size_t size) +const JSPandaFile *JSPandaFileManager::LoadJSPandaFile(const std::string &filename, const void *buffer, size_t size) { if (buffer == nullptr || size == 0) { return nullptr; @@ -66,7 +79,7 @@ const JSPandaFile *JSPandaFileManager::LoadBufferAbc(const std::string &filename if (pf == nullptr) { return nullptr; } - jsPandaFile = CreateJSPandaFile(pf.release(), desc); + jsPandaFile = GenerateJSPandaFile(pf.release(), desc); return jsPandaFile; } @@ -142,6 +155,11 @@ void JSPandaFileManager::DecreaseRefJSPandaFile(const JSPandaFile *jsPandaFile) ReleaseJSPandaFile(jsPandaFile); } +JSPandaFile *JSPandaFileManager::NewJSPandaFile(const panda_file::File *pf, const CString &desc) +{ + return new JSPandaFile(pf, desc); +} + void JSPandaFileManager::ReleaseJSPandaFile(const JSPandaFile *jsPandaFile) { if (jsPandaFile == nullptr) { @@ -162,11 +180,11 @@ tooling::ecmascript::PtJSExtractor *JSPandaFileManager::GetOrCreatePtJSExtractor return const_cast(existJSPandaFile)->GetOrCreatePtJSExtractor(); } -const JSPandaFile *JSPandaFileManager::CreateJSPandaFile(const panda_file::File *pf, const CString &desc) +const JSPandaFile *JSPandaFileManager::GenerateJSPandaFile(const panda_file::File *pf, const CString &desc) { ASSERT(GetJSPandaFile(pf) == nullptr); - JSPandaFile *newJsPandaFile = new JSPandaFile(pf, desc); + JSPandaFile *newJsPandaFile = NewJSPandaFile(pf, desc); PandaFileTranslator::TranslateClasses(newJsPandaFile, ENTRY_FUNCTION_NAME); { @@ -232,7 +250,7 @@ void JSPandaFileManager::RemoveJSPandaFile(void *pointer, void *data) if (pointer == nullptr || data == nullptr) { return; } - auto jsPandaFile = reinterpret_cast(pointer); + auto jsPandaFile = static_cast(pointer); LOG_ECMA(INFO) << "RemoveJSPandaFile " << jsPandaFile->GetPandaFile()->GetFilename(); // dec ref in filemanager JSPandaFileManager *jsPandaFileManager = static_cast(data); diff --git a/ecmascript/jspandafile/js_pandafile_manager.h b/ecmascript/jspandafile/js_pandafile_manager.h index 8fd9891631..d44695bc97 100644 --- a/ecmascript/jspandafile/js_pandafile_manager.h +++ b/ecmascript/jspandafile/js_pandafile_manager.h @@ -39,13 +39,15 @@ public: JSHandle GenerateProgram(EcmaVM *vm, const JSPandaFile *jsPandaFile); - const JSPandaFile *LoadPfAbc(const std::string &filename); + const JSPandaFile *LoadAotInfoFromPf(const std::string &filename, std::vector *infoList); - const JSPandaFile *LoadBufferAbc(const std::string &filename, const void *buffer, size_t size); + const JSPandaFile *LoadJSPandaFile(const std::string &filename); - const JSPandaFile *GetJSPandaFile(const panda_file::File *pf); + const JSPandaFile *LoadJSPandaFile(const std::string &filename, const void *buffer, size_t size); - const JSPandaFile *CreateJSPandaFile(const panda_file::File *pf, const CString &desc); + JSPandaFile *NewJSPandaFile(const panda_file::File *pf, const CString &desc); + + const JSPandaFile *GenerateJSPandaFile(const panda_file::File *pf, const CString &desc); tooling::ecmascript::PtJSExtractor *GetOrCreatePtJSExtractor(const panda_file::File *pf); @@ -72,6 +74,7 @@ private: }; void ReleaseJSPandaFile(const JSPandaFile *jsPandaFile); + const JSPandaFile *GetJSPandaFile(const panda_file::File *pf); const JSPandaFile *FindJSPandaFile(const CString &filename); void InsertJSPandaFile(const JSPandaFile *jsPandaFile); void IncreaseRefJSPandaFile(const JSPandaFile *jsPandaFile); diff --git a/ecmascript/napi/jsnapi.cpp b/ecmascript/napi/jsnapi.cpp index 9d5a086e2c..7bda66ae8f 100755 --- a/ecmascript/napi/jsnapi.cpp +++ b/ecmascript/napi/jsnapi.cpp @@ -881,7 +881,6 @@ Local FunctionRef::New(EcmaVM *vm, FunctionCallback nativeFunc, Del JSHandle current(factory->NewJSFunction(env, reinterpret_cast(Callback::RegisterCallback))); JSHandle extraInfo = factory->NewJSNativePointer(reinterpret_cast(nativeFunc), deleter, data); - vm->PushToArrayDataList(*extraInfo); current->SetFunctionExtraInfo(thread, extraInfo.GetTaggedValue()); return JSNApiHelper::ToLocal(JSHandle(current)); } @@ -918,9 +917,6 @@ Local FunctionRef::NewClassFunction(EcmaVM *vm, FunctionCallbackWit JSHandle extraInfo = factory->NewJSNativePointer(reinterpret_cast(nativeFunc), deleter, data); - if (deleter != nullptr) { - vm->PushToArrayDataList(*extraInfo); - } current->SetFunctionExtraInfo(thread, extraInfo.GetTaggedValue()); JSHandle clsPrototype = JSFunction::NewJSFunctionPrototype(thread, factory, current); diff --git a/ecmascript/object_factory-inl.h b/ecmascript/object_factory-inl.h index 23399c9783..9f96184cf2 100644 --- a/ecmascript/object_factory-inl.h +++ b/ecmascript/object_factory-inl.h @@ -56,6 +56,10 @@ JSHandle ObjectFactory::NewJSNativePointer(void *externalPointe obj->SetExternalPointer(externalPointer); obj->SetDeleter(callBack); obj->SetData(data); + + if (callBack != nullptr) { + vm_->PushToNativePointerList(static_cast(header)); + } return obj; } @@ -84,10 +88,8 @@ void ObjectFactory::NewJSIntlIcuData(const JSHandle &obj, const S &icu, const native->ResetExternalPointer(icuPoint); return; } - JSHandle pointer(thread_, NewJSNativePointer(icuPoint, callback, nullptr).GetTaggedValue()); + JSHandle pointer = NewJSNativePointer(icuPoint, callback); obj->SetIcuField(thread_, pointer.GetTaggedValue()); - // push uint8_t* to ecma array_data_list - vm_->PushToArrayDataList(*pointer); } } // namespace panda::ecmascript #endif // ECMASCRIPT_OBJECT_FACTORY_INL_H diff --git a/ecmascript/object_factory.cpp b/ecmascript/object_factory.cpp index a1e99de1aa..2b0fa37e9f 100644 --- a/ecmascript/object_factory.cpp +++ b/ecmascript/object_factory.cpp @@ -165,7 +165,6 @@ void ObjectFactory::NewJSArrayBufferData(const JSHandle &array, i JSHandle pointer = NewJSNativePointer(newData, NativeAreaAllocator::FreeBufferFunc, vm_->GetNativeAreaAllocator()); array->SetArrayBufferData(thread_, pointer.GetTaggedValue()); - vm_->PushToArrayDataList(*pointer); } JSHandle ObjectFactory::NewJSArrayBuffer(int32_t length) @@ -186,7 +185,6 @@ JSHandle ObjectFactory::NewJSArrayBuffer(int32_t length) vm_->GetNativeAreaAllocator()); arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue()); arrayBuffer->ClearBitField(); - vm_->PushToArrayDataList(*pointer); } return arrayBuffer; } @@ -205,7 +203,6 @@ JSHandle ObjectFactory::NewJSArrayBuffer(void *buffer, int32_t le JSHandle pointer = NewJSNativePointer(buffer, deleter, data); arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue()); arrayBuffer->SetShared(share); - vm_->PushToArrayDataList(*pointer); } return arrayBuffer; } @@ -250,9 +247,6 @@ void ObjectFactory::NewJSRegExpByteCodeData(const JSHandle ®exp, vo vm_->GetNativeAreaAllocator()); regexp->SetByteCodeBuffer(thread_, pointer.GetTaggedValue()); regexp->SetLength(static_cast(size)); - - // push uint8_t* to ecma array_data_list - vm_->PushToArrayDataList(*pointer); } JSHandle ObjectFactory::NewEcmaDynClass(uint32_t size, JSType type, const JSHandle &prototype) diff --git a/ecmascript/scope_info_extractor.cpp b/ecmascript/scope_info_extractor.cpp index f66a877e98..05291569dd 100644 --- a/ecmascript/scope_info_extractor.cpp +++ b/ecmascript/scope_info_extractor.cpp @@ -41,7 +41,6 @@ JSTaggedValue ScopeInfoExtractor::GenerateScopeInfo(JSThread *thread, uint16_t s JSHandle pointer = factory->NewJSNativePointer( buffer, NativeAreaAllocator::FreeObjectFunc, ecmaVm->GetNativeAreaAllocator()); - ecmaVm->PushToArrayDataList(*pointer); return pointer.GetTaggedValue(); } } // namespace panda::ecmascript diff --git a/ecmascript/snapshot/mem/snapshot.cpp b/ecmascript/snapshot/mem/snapshot.cpp index 83f88306ad..1590c5553e 100644 --- a/ecmascript/snapshot/mem/snapshot.cpp +++ b/ecmascript/snapshot/mem/snapshot.cpp @@ -26,6 +26,7 @@ #include "ecmascript/jobs/micro_job_queue.h" #include "ecmascript/js_hclass.h" #include "ecmascript/js_thread.h" +#include "ecmascript/jspandafile/js_pandafile_manager.h" #include "ecmascript/mem/c_containers.h" #include "ecmascript/mem/heap.h" #include "ecmascript/object_factory.h" @@ -116,16 +117,16 @@ void SnapShot::MakeSnapShotProgramObject(Program *program, const panda_file::Fil write.close(); } -std::unique_ptr SnapShot::DeserializeGlobalEnvAndProgram(const CString &fileName) +const JSPandaFile *SnapShot::DeserializeGlobalEnvAndProgram(const CString &abcFile, const CString &snapshotFile) { SnapShotSerialize serialize(vm_, false); serialize.GeneratedNativeMethod(); - std::pair filePath = VerifyFilePath(fileName); + std::pair filePath = VerifyFilePath(snapshotFile); if (!filePath.first) { LOG(ERROR, RUNTIME) << "snapshot file path error"; - return std::unique_ptr(); + return nullptr; } int fd = open(filePath.second.c_str(), O_CLOEXEC); // NOLINT(cppcoreguidelines-pro-type-vararg) @@ -184,11 +185,13 @@ std::unique_ptr SnapShot::DeserializeGlobalEnvAndProgram auto pf = panda_file::File::OpenFromMemory(os::mem::ConstBytePtr(ToNativePtr(panda_file_mem), file_size - hdr.panda_file_begin, os::mem::MmapDeleter), - fileName); + abcFile); close(fd); + // Snapshot file has translated + const JSPandaFile *jsPandaFile = EcmaVM::GetJSPandaFileManager()->NewJSPandaFile(pf.release(), abcFile); // redirect object field - serialize.RedirectSlot(pf.get()); - return pf; + serialize.RedirectSlot(jsPandaFile); + return jsPandaFile; } size_t SnapShot::AlignUpPageSize(size_t spaceSize) diff --git a/ecmascript/snapshot/mem/snapshot.h b/ecmascript/snapshot/mem/snapshot.h index 05dfec162a..2b2980561f 100644 --- a/ecmascript/snapshot/mem/snapshot.h +++ b/ecmascript/snapshot/mem/snapshot.h @@ -25,6 +25,7 @@ namespace panda::ecmascript { class Program; class EcmaVM; +class JSPandaFile; class SnapShot final { public: @@ -33,8 +34,8 @@ public: void MakeSnapShotProgramObject(Program *program, const panda_file::File *pf, const CString &fileName = "./snapshot"); - std::unique_ptr DeserializeGlobalEnvAndProgram( - const CString &fileName = "./snapshot"); + const JSPandaFile *DeserializeGlobalEnvAndProgram(const CString &abcFile, + const CString &snapshotFile = "./snapshot"); private: struct Header { diff --git a/ecmascript/snapshot/mem/snapshot_serialize.cpp b/ecmascript/snapshot/mem/snapshot_serialize.cpp index 4ce6bc7938..1dca2496ca 100644 --- a/ecmascript/snapshot/mem/snapshot_serialize.cpp +++ b/ecmascript/snapshot/mem/snapshot_serialize.cpp @@ -66,6 +66,7 @@ #include "ecmascript/js_map_iterator.h" #include "ecmascript/js_set_iterator.h" #include "ecmascript/js_tagged_value-inl.h" +#include "ecmascript/jspandafile/js_pandafile.h" #include "ecmascript/mem/heap.h" #include "ecmascript/mem/heap_region_allocator.h" #include "ecmascript/mem/space-inl.h" @@ -738,13 +739,16 @@ void SnapShotSerialize::ExtendObjectArray() addressSlot_ = ToUintPtr(addr); } -void SnapShotSerialize::RedirectSlot(const panda_file::File *pf) +void SnapShotSerialize::RedirectSlot(const JSPandaFile *jsPandaFile) { SnapShotSpace *space = vm_->GetHeap()->GetSnapShotSpace(); EcmaStringTable *stringTable = vm_->GetEcmaStringTable(); + const panda_file::File *pf = jsPandaFile->GetPandaFile(); + uint32_t methodNums = jsPandaFile->GetNumMethods(); + JSMethod *methods = jsPandaFile->GetMethods(); size_t others = 0; - space->EnumerateRegions([stringTable, &others, this, pf](Region *current) { + space->EnumerateRegions([stringTable, &others, this, pf, methods, &methodNums](Region *current) { size_t allocated = current->GetAllocatedBytes(); uintptr_t begin = current->GetBegin(); uintptr_t end = begin + allocated; @@ -755,7 +759,10 @@ void SnapShotSerialize::RedirectSlot(const panda_file::File *pf) auto method = reinterpret_cast(begin); method->SetPandaFile(pf); method->SetBytecodeArray(method->GetInstructions()); - vm_->frameworkProgramMethods_.emplace_back(method); + if (memcpy_s(methods + (--methodNums), METHOD_SIZE, method, METHOD_SIZE) != EOK) { + LOG_ECMA(FATAL) << "memcpy_s failed"; + UNREACHABLE(); + } begin += METHOD_SIZE; if (begin >= end) { others = others - i - 1; @@ -775,7 +782,10 @@ void SnapShotSerialize::RedirectSlot(const panda_file::File *pf) auto method = reinterpret_cast(begin); method->SetPandaFile(pf); method->SetBytecodeArray(method->GetInstructions()); - vm_->frameworkProgramMethods_.emplace_back(method); + if (memcpy_s(methods + (--methodNums), METHOD_SIZE, method, METHOD_SIZE) != EOK) { + LOG_ECMA(FATAL) << "memcpy_s failed"; + UNREACHABLE(); + } begin += METHOD_SIZE; if (begin >= end) { others = slot.GetObjectSize() - i - 1; diff --git a/ecmascript/snapshot/mem/snapshot_serialize.h b/ecmascript/snapshot/mem/snapshot_serialize.h index e732a00c09..4529f552dc 100644 --- a/ecmascript/snapshot/mem/snapshot_serialize.h +++ b/ecmascript/snapshot/mem/snapshot_serialize.h @@ -26,6 +26,7 @@ namespace panda::ecmascript { class EcmaVM; +class JSPandaFile; class SnapShotSerialize final { public: @@ -34,7 +35,7 @@ public: void Serialize(TaggedObject *objectHeader, CQueue *queue, std::unordered_map *data); - void RedirectSlot(const panda_file::File *pf); + void RedirectSlot(const JSPandaFile *jsPandaFile); void SerializePandaFileMethod(); void SetProgramSerializeStart()