From e6a8f39b148263c1bf80d2412990b810814075bb Mon Sep 17 00:00:00 2001 From: liujia178 Date: Tue, 2 Jul 2024 17:24:28 +0800 Subject: [PATCH 01/12] Fix Cross-Platform AOT Macro Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAA0J3 Signed-off-by: liujia178 Change-Id: 02f42f42abd9c346af2f665850d75e784cb66896 --- BUILD.gn | 4 ++++ ecmascript/compiler/aot_file/an_file_data_manager.cpp | 4 ++-- ecmascript/compiler/aot_file/an_file_data_manager.h | 2 +- ecmascript/compiler/aot_file/an_file_info.cpp | 2 +- ecmascript/compiler/aot_file/an_file_info.h | 2 +- ecmascript/compiler/aot_file/aot_file_manager.cpp | 8 ++++---- ecmascript/compiler/aot_file/aot_file_manager.h | 4 ++-- ecmascript/ecma_context.cpp | 2 +- ecmascript/ecma_context.h | 4 ++-- ecmascript/napi/include/jsnapi_expo.h | 2 +- ecmascript/napi/jsnapi_expo.cpp | 4 ++-- ecmascript/snapshot/mem/snapshot.cpp | 4 ++-- ecmascript/snapshot/mem/snapshot.h | 2 +- 13 files changed, 24 insertions(+), 20 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 486aafa3e..90a9d0cab 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -322,6 +322,10 @@ config("ark_jsruntime_common_config") { defines += [ "IS_PUBLIC_VERSION" ] } + if (is_arkui_x) { + defines += [ "CROSS_PLATFORM" ] + } + if (target_os == "android") { defines += [ "ANDROID_PLATFORM" ] } diff --git a/ecmascript/compiler/aot_file/an_file_data_manager.cpp b/ecmascript/compiler/aot_file/an_file_data_manager.cpp index 1008c6185..95d1b935e 100644 --- a/ecmascript/compiler/aot_file/an_file_data_manager.cpp +++ b/ecmascript/compiler/aot_file/an_file_data_manager.cpp @@ -80,7 +80,7 @@ bool AnFileDataManager::SafeLoad(const std::string &fileName, Type type, [[maybe if (aotFileInfo != nullptr) { return true; } -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) return UnsafeLoadFromAOT(fileName, cb); #else return UnsafeLoadFromAOT(fileName); @@ -142,7 +142,7 @@ bool AnFileDataManager::UnsafeLoadFromAOT(const std::string &fileName) return UnsafeLoadFromAOTInternal(fileName, info); } -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) bool AnFileDataManager::UnsafeLoadFromAOT(const std::string &fileName, std::function cb) { diff --git a/ecmascript/compiler/aot_file/an_file_data_manager.h b/ecmascript/compiler/aot_file/an_file_data_manager.h index 2f86c7307..141f03692 100644 --- a/ecmascript/compiler/aot_file/an_file_data_manager.h +++ b/ecmascript/compiler/aot_file/an_file_data_manager.h @@ -71,7 +71,7 @@ private: std::shared_ptr UnsafeFind(const std::string &fileName) const; bool UnsafeLoadFromAOTInternal(const std::string &fileName, std::shared_ptr &info); bool UnsafeLoadFromAOT(const std::string &fileName); -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) bool UnsafeLoadFromAOT(const std::string &fileName, std::function cb); #endif diff --git a/ecmascript/compiler/aot_file/an_file_info.cpp b/ecmascript/compiler/aot_file/an_file_info.cpp index 4cd402c64..ee79a20cc 100644 --- a/ecmascript/compiler/aot_file/an_file_info.cpp +++ b/ecmascript/compiler/aot_file/an_file_info.cpp @@ -96,7 +96,7 @@ bool AnFileInfo::Load(const std::string &filename) return LoadInternal(filename); } -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) bool AnFileInfo::Load(const std::string &filename, [[maybe_unused]] std::function ReadAOTCallBack) { diff --git a/ecmascript/compiler/aot_file/an_file_info.h b/ecmascript/compiler/aot_file/an_file_info.h index 936988c3a..f59e54f81 100644 --- a/ecmascript/compiler/aot_file/an_file_info.h +++ b/ecmascript/compiler/aot_file/an_file_info.h @@ -94,7 +94,7 @@ private: using EntryKey = std::pair; bool LoadInternal(const std::string &filename); bool Load(const std::string &filename); -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) bool Load(const std::string &filename, [[maybe_unused]] std::function ReadAOTCallBack); #endif diff --git a/ecmascript/compiler/aot_file/aot_file_manager.cpp b/ecmascript/compiler/aot_file/aot_file_manager.cpp index 1762d4033..0a084b05b 100644 --- a/ecmascript/compiler/aot_file/aot_file_manager.cpp +++ b/ecmascript/compiler/aot_file/aot_file_manager.cpp @@ -52,7 +52,7 @@ using CommonStubCSigns = kungfu::CommonStubCSigns; using BytecodeStubCSigns = kungfu::BytecodeStubCSigns; using SnapshotGlobalData = kungfu::SnapshotGlobalData; -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) JsAotReaderCallback AOTFileManager::jsAotReader_ = nullptr; #endif @@ -69,7 +69,7 @@ void AOTFileManager::Iterate(const RootVisitor &v) } } -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) void AOTFileManager::SetJsAotReader(JsAotReaderCallback cb) { jsAotReader_ = cb; @@ -101,7 +101,7 @@ void AOTFileManager::LoadStubFile(const std::string &fileName) bool AOTFileManager::LoadAnFile(const std::string &fileName) { AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance(); -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) return anFileDataManager->SafeLoad(fileName, AnFileDataManager::Type::AOT, GetJsAotReader()); #else return anFileDataManager->SafeLoad(fileName, AnFileDataManager::Type::AOT); @@ -112,7 +112,7 @@ bool AOTFileManager::LoadAiFile([[maybe_unused]] const std::string &filename) { Snapshot snapshot(vm_); #if !WIN_OR_MAC_OR_IOS_PLATFORM - #if defined(ANDROID_PLATFORM) + #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) return snapshot.Deserialize(SnapshotType::AI, filename.c_str(), GetJsAotReader()); #else return snapshot.Deserialize(SnapshotType::AI, filename.c_str()); diff --git a/ecmascript/compiler/aot_file/aot_file_manager.h b/ecmascript/compiler/aot_file/aot_file_manager.h index bf0b90993..2a9c7d914 100644 --- a/ecmascript/compiler/aot_file/aot_file_manager.h +++ b/ecmascript/compiler/aot_file/aot_file_manager.h @@ -153,7 +153,7 @@ public: static constexpr char FILE_EXTENSION_AI[] = ".ai"; static constexpr uint32_t STUB_FILE_INDEX = 1; -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) static void SetJsAotReader(JsAotReaderCallback cb); static JsAotReaderCallback GetJsAotReader(); #endif @@ -209,7 +209,7 @@ private: ObjectFactory *factory_ {nullptr}; AIDatum aiDatum_ {}; kungfu::ArkStackMapParser *arkStackMapParser_ {nullptr}; -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) static JsAotReaderCallback jsAotReader_; #endif diff --git a/ecmascript/ecma_context.cpp b/ecmascript/ecma_context.cpp index 22b519b8c..4695b5d7e 100644 --- a/ecmascript/ecma_context.cpp +++ b/ecmascript/ecma_context.cpp @@ -1110,7 +1110,7 @@ bool EcmaContext::LoadAOTFiles(const std::string& aotFileName) return LoadAOTFilesInternal(aotFileName); } -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) bool EcmaContext::LoadAOTFiles(const std::string& aotFileName, std::function cb) { diff --git a/ecmascript/ecma_context.h b/ecmascript/ecma_context.h index 4b1bfeb7e..71ad2b0ca 100644 --- a/ecmascript/ecma_context.h +++ b/ecmascript/ecma_context.h @@ -92,7 +92,7 @@ using HostPromiseRejectionTracker = void (*)(const EcmaVM* vm, PromiseRejectionEvent operation, void* data); using PromiseRejectCallback = void (*)(void* info); -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) using JsAotReaderCallback = std::function; #endif class EcmaContext { @@ -627,7 +627,7 @@ private: std::string_view entryPoint, JSHandle &func, bool executeFromJob); bool LoadAOTFilesInternal(const std::string& aotFileName); bool LoadAOTFiles(const std::string &aotFileName); -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) bool LoadAOTFiles(const std::string &aotFileName, std::function cb); #endif diff --git a/ecmascript/napi/include/jsnapi_expo.h b/ecmascript/napi/include/jsnapi_expo.h index e85f07f7c..3894d6bb0 100644 --- a/ecmascript/napi/include/jsnapi_expo.h +++ b/ecmascript/napi/include/jsnapi_expo.h @@ -1380,7 +1380,7 @@ public: // aot load static void LoadAotFileInternal(EcmaVM *vm, const std::string &moduleName, std::string &aotFileName); static void LoadAotFile(EcmaVM *vm, const std::string &moduleName); -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) static void LoadAotFile(EcmaVM *vm, [[maybe_unused]] const std::string &bundleName, const std::string &moduleName, std::function cb); diff --git a/ecmascript/napi/jsnapi_expo.cpp b/ecmascript/napi/jsnapi_expo.cpp index 3ed8e54c0..7124a5663 100644 --- a/ecmascript/napi/jsnapi_expo.cpp +++ b/ecmascript/napi/jsnapi_expo.cpp @@ -4431,7 +4431,7 @@ void JSNApi::LoadAotFileInternal(EcmaVM *vm, const std::string &moduleName, std: if (vm->GetJSOptions().WasAOTOutputFileSet()) { aotFileName = vm->GetJSOptions().GetAOTOutputFile(); } -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) else if (vm->GetJSOptions().GetEnableAOT()) #else else if (ecmascript::AnFileDataManager::GetInstance()->IsEnable()) @@ -4465,7 +4465,7 @@ void JSNApi::LoadAotFile(EcmaVM *vm, const std::string &moduleName) ecmascript::JSPandaFileExecutor::BindPreloadedPandaFilesToAOT(vm, moduleName); } -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) void JSNApi::LoadAotFile(EcmaVM *vm, [[maybe_unused]] const std::string &bundleName, const std::string &moduleName, std::function cb) { diff --git a/ecmascript/snapshot/mem/snapshot.cpp b/ecmascript/snapshot/mem/snapshot.cpp index 8ecc92cd3..4f7b5dfa1 100644 --- a/ecmascript/snapshot/mem/snapshot.cpp +++ b/ecmascript/snapshot/mem/snapshot.cpp @@ -164,7 +164,7 @@ bool Snapshot::DeserializeInternal(SnapshotType type, const CString &snapshotFil processor.DeserializeObjectExcludeString(oldSpaceBegin, hdr.oldSpaceObjSize, hdr.nonMovableObjSize, hdr.machineCodeObjSize, hdr.snapshotObjSize, hdr.hugeObjSize); -#if !defined(ANDROID_PLATFORM) +#if !defined(CROSS_PLATFORM) FileUnMap(MemMap(fileMap.GetOriginAddr(), hdr.pandaFileBegin)); #endif std::shared_ptr jsPandaFile; @@ -198,7 +198,7 @@ bool Snapshot::Deserialize(SnapshotType type, const CString &snapshotFile, bool return DeserializeInternal(type, snapshotFile, processor, fileMap); } -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) bool Snapshot::Deserialize(SnapshotType type, const CString &snapshotFile, [[maybe_unused]] std::function ReadAOTCallBack, bool isBuiltins) { diff --git a/ecmascript/snapshot/mem/snapshot.h b/ecmascript/snapshot/mem/snapshot.h index a6b6215e4..8bf133a97 100644 --- a/ecmascript/snapshot/mem/snapshot.h +++ b/ecmascript/snapshot/mem/snapshot.h @@ -41,7 +41,7 @@ public: bool DeserializeInternal(SnapshotType type, const CString &snapshotFile, SnapshotProcessor &processor, MemMap &fileMap); bool Deserialize(SnapshotType type, const CString &snapshotFile, bool isBuiltins = false); -#if defined(ANDROID_PLATFORM) +#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) bool Deserialize(SnapshotType type, const CString &snapshotFile, [[maybe_unused]] std::function ReadAOTCallBack, bool isBuiltins = false); #endif -- Gitee From 60a32fac1e8d9b2d1769adc669089b9cd00b5fc9 Mon Sep 17 00:00:00 2001 From: h00600710 Date: Fri, 28 Jun 2024 10:11:51 +0800 Subject: [PATCH 02/12] [BaselineJit]Handle performance issue Handle performance issue15 Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IA9GHP Change-Id: I9c999e23b503cf423bd963f88e5138509b128740 Signed-off-by: h00600710 --- ecmascript/compiler/baseline/baseline_stubs.cpp | 4 +++- ecmascript/compiler/stub_builder.cpp | 8 ++++---- ecmascript/compiler/stub_builder.h | 6 ++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ecmascript/compiler/baseline/baseline_stubs.cpp b/ecmascript/compiler/baseline/baseline_stubs.cpp index 9bf59c22d..fe6dac43c 100644 --- a/ecmascript/compiler/baseline/baseline_stubs.cpp +++ b/ecmascript/compiler/baseline/baseline_stubs.cpp @@ -6394,6 +6394,7 @@ void BaselineUpdateHotnessStubBuilder::GenerateCircuit() GateRef method = GetMethodFromFunction(func); GateRef hotnessCounter = GetHotnessCounterFromMethod(method); GateRef profileTypeInfo = GetProfileTypeInfoFromFunction(func); + GateRef acc = GetAccFromFrame(frame); auto env = GetEnvironment(); DEFVARIABLE(varProfileTypeInfo, VariableType::JS_ANY(), profileTypeInfo); @@ -6421,7 +6422,8 @@ void BaselineUpdateHotnessStubBuilder::GenerateCircuit() BRANCH(HasPendingException(glue), &handleException, &noException); Bind(&handleException); { - Jump(&exitLabel); + DISPATCH_LAST(); + Return(); } Bind(&noException); { diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index c6c8bbd63..6fd1596e5 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -5881,14 +5881,14 @@ GateRef StubBuilder::FastToBooleanBaseline(GateRef value, bool flag) Branch(TaggedIsNumber(value), &isNumber, ¬Number); Bind(¬Number); { - Branch(TaggedIsString(value), &isString, ¬String); + Branch(IsString(value), &isString, ¬String); Bind(&isString); { auto len = GetLengthFromString(value); Branch(Int32Equal(len, Int32(0)), &returnFalse, &returnTrue); } Bind(¬String); - Branch(env_->GetBuilder()->TaggedIsBigInt(value), &isBigint, &returnTrue); + Branch(TaggedObjectIsBigInt(value), &isBigint, &returnTrue); Bind(&isBigint); { auto len = Load(VariableType::INT32(), value, IntPtr(BigInt::LENGTH_OFFSET)); @@ -6120,14 +6120,14 @@ GateRef StubBuilder::FastToBooleanWithProfileBaseline(GateRef value, ProfileOper Branch(TaggedIsNumber(value), &isNumber, ¬Number); Bind(¬Number); { - Branch(TaggedIsString(value), &isString, ¬String); + Branch(IsString(value), &isString, ¬String); Bind(&isString); { auto len = GetLengthFromString(value); Branch(Int32Equal(len, Int32(0)), &returnFalse, &returnTrue); } Bind(¬String); - Branch(env_->GetBuilder()->TaggedIsBigInt(value), &isBigint, &returnTrue); + Branch(TaggedObjectIsBigInt(value), &isBigint, &returnTrue); Bind(&isBigint); { auto len = Load(VariableType::INT32(), value, IntPtr(BigInt::LENGTH_OFFSET)); diff --git a/ecmascript/compiler/stub_builder.h b/ecmascript/compiler/stub_builder.h index aaf49b5d3..9edab91fe 100644 --- a/ecmascript/compiler/stub_builder.h +++ b/ecmascript/compiler/stub_builder.h @@ -47,7 +47,8 @@ using namespace panda::ecmascript; #ifndef NDEBUG #define ASM_ASSERT(messageId, condition) \ - if (!GetEnvironment()->GetCircuit()->IsOptimizedOrFastJit()) { \ + if (!GetEnvironment()->GetCircuit()->IsOptimizedOrFastJit() && \ + !GetEnvironment()->IsBaselineBuiltin()) { \ SUBENTRY(messageId, condition); \ EXITENTRY(); \ } @@ -55,7 +56,8 @@ using namespace panda::ecmascript; SUBENTRY_WITH_GLUE(messageId, condition, glue) #elif defined(ENABLE_ASM_ASSERT) #define ASM_ASSERT(messageId, condition) \ - if (!GetEnvironment()->GetCircuit()->IsOptimizedOrFastJit()) { \ + if (!GetEnvironment()->GetCircuit()->IsOptimizedOrFastJit() && \ + !GetEnvironment()->IsBaselineBuiltin()) { \ SUBENTRY(messageId, condition); \ EXITENTRY(); \ } -- Gitee From b91e5745daca5ff33c2e67fcc255ff16681f37f0 Mon Sep 17 00:00:00 2001 From: zhangyouyou Date: Tue, 9 Jul 2024 10:39:51 +0800 Subject: [PATCH 03/12] Add decodeURIComponent tests Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IABK4Y Description:Add decodeURIComponent tests Signed-off-by: zhangyouyou --- test/moduletest/BUILD.gn | 1 + .../decodeuricomponent/decodeuricomponent.js | 31 +++++++++++++++++-- .../decodeuricomponent/expect_output.txt | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/test/moduletest/BUILD.gn b/test/moduletest/BUILD.gn index 5b61ef935..0b72536ce 100644 --- a/test/moduletest/BUILD.gn +++ b/test/moduletest/BUILD.gn @@ -463,6 +463,7 @@ group("ark_asm_single_step_test") { "concurrent", "container", "dataproperty", + "decodeuricomponent", "dynamicimport", "dyninstruction", "ecmastringtable", diff --git a/test/moduletest/decodeuricomponent/decodeuricomponent.js b/test/moduletest/decodeuricomponent/decodeuricomponent.js index 832ecaafc..00b927833 100644 --- a/test/moduletest/decodeuricomponent/decodeuricomponent.js +++ b/test/moduletest/decodeuricomponent/decodeuricomponent.js @@ -19,7 +19,6 @@ * @tc.type: FUNC * @tc.require: issueI7CTF7 */ - let uri="%c2%aa%66%55%58%c2%83%c2%93%00%c2%89%c3%96%08%58%c2%b4%c3%bd%46"; let uri_encode=decodeURIComponent(uri); print(encodeURIComponent(uri_encode)); @@ -85,4 +84,32 @@ print(decodeURIComponent(uri0)); print(decodeURIComponent(uri11)); print(decodeURIComponent(uri2)); print(decodeURIComponent(uri3)); -print(decodeURIComponent(uri4)); \ No newline at end of file +print(decodeURIComponent(uri4)); + +{ + var result = true; + var arr = [ + [0x00, 0x2F], + [0x47, 0x60], + ]; + for (var i = 0; i < arr.length; i++) { + for (var j = arr[i][0]; j <= arr[i][1]; j++) { + try { + decodeURIComponent("%" + String.fromCharCode(j)+ "1"); + decodeURIComponent("%" + "1" + String.fromCharCode(j)); + decodeURIComponent("%C0%" + String.fromCharCode(j, j)); + decodeURIComponent("%E0%" + String.fromCharCode(j, j) + "%A0"); + decodeURIComponent("%E0" + "%A0%" + String.fromCharCode(j, j)); + decodeURIComponent("%F0%" + String.fromCharCode(j, j) + "%A0%A0"); + decodeURIComponent("%F0" + "%A0%" + String.fromCharCode(j, j) + "%A0"); + decodeURIComponent("%F0" + "%A0%A0%" + String.fromCharCode(j, j)); + result = false; + } catch (e) { + if ((e instanceof URIError) !== true) { + result = false; + } + } + } + } + print(result) +} \ No newline at end of file diff --git a/test/moduletest/decodeuricomponent/expect_output.txt b/test/moduletest/decodeuricomponent/expect_output.txt index 4c3749fec..d4b740515 100644 --- a/test/moduletest/decodeuricomponent/expect_output.txt +++ b/test/moduletest/decodeuricomponent/expect_output.txt @@ -29,3 +29,4 @@ https://www.runoob.com/my test.php?name=ståle&car=saab/jfdlskafasfd https://www.runoob.com/my test.php?name=ståle&car=saab/2389018203 https://www.runoob.com/my test.php?name=ståle&car=saab/jfdlskafasfd/jd2931dsafdsa https://www.runoob.com/my test.php?name=ståle&car=saab/jfdlskafasfd/jd2931dsafdsa/jd2931wjeiojfwre +true -- Gitee From 80681266d03f52d243a261833fe7948d7d3524b6 Mon Sep 17 00:00:00 2001 From: xiaoweidong Date: Fri, 5 Jul 2024 23:32:19 +0800 Subject: [PATCH 04/12] [JIT] Fix jit task tool destory before vm destory 1. jit task pool destory will use threadid from jitthread when runtime destory, but jit thread may be destoryed before task pool destory. so use thread id directly 2. add jit trace with funcname, and intall trace 3. remove unused compile log Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAB0IS Change-Id: I310797eb336106cd5e06767fb36ef876b22bc895 Signed-off-by: xiaoweidong --- ecmascript/compiler/pass_manager.cpp | 3 --- ecmascript/jit/jit.cpp | 5 ++++- ecmascript/jit/jit_task.cpp | 5 +++-- ecmascript/jit/jit_task.h | 6 ++++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ecmascript/compiler/pass_manager.cpp b/ecmascript/compiler/pass_manager.cpp index 66e4c8390..f5bc8935f 100644 --- a/ecmascript/compiler/pass_manager.cpp +++ b/ecmascript/compiler/pass_manager.cpp @@ -85,9 +85,6 @@ bool JitPassManager::Compile(JSHandle &profileTypeInfo, << "] recordName [" << recordName << "] log:" << "\033[0m"; } bool hasTypes = jsPandaFile->HasTSTypes(recordName); - if (UNLIKELY(!hasTypes)) { - LOG_COMPILER(INFO) << "record: " << recordName << " has no types"; - } if (compilationEnv_->GetJSOptions().IsEnableJITPGO()) { jitProfiler_ = compilationEnv_->GetPGOProfiler()->GetJITProfile(); static_cast(compilationEnv_)->SetProfileTypeInfo(profileTypeInfo); diff --git a/ecmascript/jit/jit.cpp b/ecmascript/jit/jit.cpp index 3c54de62f..25daf99b5 100644 --- a/ecmascript/jit/jit.cpp +++ b/ecmascript/jit/jit.cpp @@ -247,7 +247,6 @@ void Jit::Compile(EcmaVM *vm, JSHandle &jsFunction, CompilerTier tie return; } - ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "JIT::Compile"); Method *method = Method::Cast(jsFunction->GetMethod().GetTaggedObject()); CString fileDesc = method->GetJSPandaFile()->GetJSPandaFileDesc(); CString methodName = fileDesc + ":" + method->GetRecordNameStr() + "." + CString(method->GetMethodName()); @@ -255,6 +254,8 @@ void Jit::Compile(EcmaVM *vm, JSHandle &jsFunction, CompilerTier tie jit->GetJitDfx()->SetBundleName(vm->GetBundleName()); jit->GetJitDfx()->SetPidNumber(vm->GetJSThread()->GetThreadId()); CString methodInfo = methodName + ", bytecode size:" + ToCString(codeSize); + ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, ConvertToStdString("JIT::Compile:" + methodInfo)); + uint32_t maxSize = 9000; if (vm->GetJSOptions().IsEnableJitFastCompile()) { maxSize = 15; // 15 is method codesize threshold during fast compiling @@ -389,6 +390,8 @@ void Jit::InstallTasks(uint32_t threadId) { LockHolder holder(installJitTasksDequeMtx_); auto &taskQueue = installJitTasks_[threadId]; + ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, ConvertToStdString("Jit::InstallTasks count:" + ToCString(taskQueue.size()))); + for (auto it = taskQueue.begin(); it != taskQueue.end(); it++) { std::shared_ptr task = *it; // check task state diff --git a/ecmascript/jit/jit_task.cpp b/ecmascript/jit/jit_task.cpp index 8dfee880c..888bf4336 100644 --- a/ecmascript/jit/jit_task.cpp +++ b/ecmascript/jit/jit_task.cpp @@ -371,7 +371,8 @@ bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex) } DISALLOW_HEAP_ACCESS; - ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "JIT::Compile"); + CString info = "compile method:" + jitTask_->GetMethodName(); + ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, ConvertToStdString("JIT::Compile:" + info)); // JitCompileMode ASYNC // check init ok jitTask_->SetRunState(RunState::RUNNING); @@ -385,7 +386,7 @@ bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex) if (jitTask_->GetJsFunction().GetAddress() == 0) { // for unit test } else { - CString info = "compile method:" + jitTask_->GetMethodName() + ", in jit thread"; + info = info + ", in jit thread"; Jit::TimeScope scope(jitTask_->GetHostThread()->GetEcmaVM(), info, jitTask_->GetCompilerTier()); jitTask_->Optimize(); diff --git a/ecmascript/jit/jit_task.h b/ecmascript/jit/jit_task.h index 6b45b0167..a39bb90b8 100644 --- a/ecmascript/jit/jit_task.h +++ b/ecmascript/jit/jit_task.h @@ -52,6 +52,7 @@ public: { LockHolder lock(jitTaskPoolMutex_); compilerVm_ = vm; + threadId_ = compilerVm_->GetJSThread()->GetThreadId(); jitTaskPoolCV_.SignalAll(); } @@ -79,14 +80,15 @@ public: void Destroy() { - Taskpool::Destroy(compilerVm_->GetJSThread()->GetThreadId()); + Taskpool::Destroy(threadId_); } private: uint32_t TheMostSuitableThreadNum(uint32_t threadNum) const override; - EcmaVM *compilerVm_; + EcmaVM *compilerVm_ { nullptr }; Mutex jitTaskPoolMutex_; ConditionVariable jitTaskPoolCV_; + int32_t threadId_ { -1 }; }; class JitTask { -- Gitee From b202288afea7705cbd2a9cfb7a40ec26f9315de9 Mon Sep 17 00:00:00 2001 From: shaoyijiang Date: Fri, 28 Jun 2024 16:52:00 +0800 Subject: [PATCH 05/12] Get more frame info for dfx 1.Remove the jit frame from the crash main thread scene 2.Get more native frames info for dfx 3.Fix prctl failure caused by tag.length() > PR_SET_VMA_ANON_NAME_MAX_LEN Issue: IA6Z36 Signed-off-by: shaoyijiang Change-Id: I8dad456668519c80a0a45f22343f7304fb4c0cc5 --- ecmascript/dfx/stackinfo/js_stackinfo.cpp | 141 +++++++++++++++--- ecmascript/dfx/stackinfo/js_stackinfo.h | 10 ++ ecmascript/frames.h | 45 ++++++ .../jspandafile/js_pandafile_manager.cpp | 5 + 4 files changed, 183 insertions(+), 18 deletions(-) diff --git a/ecmascript/dfx/stackinfo/js_stackinfo.cpp b/ecmascript/dfx/stackinfo/js_stackinfo.cpp index 22346f523..a6e9c6ec2 100644 --- a/ecmascript/dfx/stackinfo/js_stackinfo.cpp +++ b/ecmascript/dfx/stackinfo/js_stackinfo.cpp @@ -45,6 +45,12 @@ bool IsFastJitFunctionFrame(const FrameType frameType) return frameType == FrameType::FASTJIT_FUNCTION_FRAME || frameType == FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME; } +bool IsFastJitFunctionFrame(uintptr_t frameType) +{ + return static_cast(frameType) == FrameType::FASTJIT_FUNCTION_FRAME || + static_cast(frameType) == FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME; +} + std::string JsStackInfo::BuildMethodTrace(Method *method, uint32_t pcOffset, bool enableStackSourceFile) { std::string data; @@ -469,16 +475,37 @@ bool ArkFrameCheck(uintptr_t frameType) static_cast(frameType) == FrameType::ASM_INTERPRETER_ENTRY_FRAME; } -bool IsFunctionFrame(uintptr_t frameType) +bool IsJsFunctionFrame(uintptr_t frameType) { return static_cast(frameType) == FrameType::ASM_INTERPRETER_FRAME || static_cast(frameType) == FrameType::INTERPRETER_CONSTRUCTOR_FRAME || static_cast(frameType) == FrameType::INTERPRETER_FRAME || - static_cast(frameType) == FrameType::INTERPRETER_FAST_NEW_FRAME || - static_cast(frameType) == FrameType::OPTIMIZED_JS_FUNCTION_FRAME || + static_cast(frameType) == FrameType::INTERPRETER_FAST_NEW_FRAME; +} + +bool IsNativeFunctionFrame(uintptr_t frameType) +{ + return static_cast(frameType) == FrameType::OPTIMIZED_FRAME || + static_cast(frameType) == FrameType::BASELINE_BUILTIN_FRAME || + static_cast(frameType) == FrameType::ASM_BRIDGE_FRAME || + static_cast(frameType) == FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME || + static_cast(frameType) == FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME || static_cast(frameType) == FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME || - static_cast(frameType) == FrameType::FASTJIT_FUNCTION_FRAME || - static_cast(frameType) == FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME; + static_cast(frameType) == FrameType::OPTIMIZED_JS_FUNCTION_FRAME || + static_cast(frameType) == FrameType::LEAVE_FRAME || + static_cast(frameType) == FrameType::LEAVE_FRAME_WITH_ARGV || + static_cast(frameType) == FrameType::BUILTIN_CALL_LEAVE_FRAME || + static_cast(frameType) == FrameType::BUILTIN_FRAME || + static_cast(frameType) == FrameType::BUILTIN_ENTRY_FRAME || + static_cast(frameType) == FrameType::BUILTIN_FRAME_WITH_ARGV || + static_cast(frameType) == FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME || + static_cast(frameType) == FrameType::ASM_INTERPRETER_BRIDGE_FRAME; +} + +bool IsAotFunctionFrame(uintptr_t frameType) +{ + return static_cast(frameType) == FrameType::OPTIMIZED_JS_FUNCTION_FRAME || + static_cast(frameType) == FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME; } std::optional JSStackTrace::ReadMethodInfo(panda_file::MethodDataAccessor &mda) @@ -524,8 +551,11 @@ CVector JSStackTrace::ReadAllMethodInfos(std::shared_ptr JSStackTrace::TranslateByteCodePc(uintptr_t realPc, const CVector &vec) { + if (vec.size() == 0) { + LOG_ECMA(ERROR) << "Translate bytecode pc failed, vec is empty."; + return std::nullopt; + } int32_t left = 0; - ASSERT(vec.size() > 0); int32_t right = static_cast(vec.size()) - 1; for (; left <= right;) { int32_t mid = (left + right) / 2; @@ -540,6 +570,7 @@ std::optional JSStackTrace::TranslateByteCodePc(uintptr_t realPc, cons right = mid -1; } } + LOG_ECMA(ERROR) << "Translate bytecode pc failed, pc: " << std::hex << realPc; return std::nullopt; } @@ -555,7 +586,7 @@ void SaveFuncName(EntityId entityId, const std::string &name) template void ParseJsFrameInfo(JSPandaFile *jsPandaFile, DebugInfoExtractor *debugExtractor, - EntityId methodId, uintptr_t offset, T &jsFrame, SourceMap *sourceMap = nullptr) + EntityId methodId, uintptr_t offset, T &jsFrame, SourceMap *sourceMap) { if (jsPandaFile == nullptr) { LOG_ECMA(ERROR) << "Parse jsFrame info failed, jsPandaFile is nullptr."; @@ -661,6 +692,7 @@ uintptr_t GetBytecodeOffset(void *ctx, ReadMemFunc readMem, uintptr_t frameType, uintptr_t bytecodePc = 0; FrameType type = static_cast(frameType); switch (type) { + // return bytecode pc case FrameType::ASM_INTERPRETER_FRAME: case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: { currentPtr -= AsmInterpretedFrame::GetTypeOffset(); @@ -675,17 +707,80 @@ uintptr_t GetBytecodeOffset(void *ctx, ReadMemFunc readMem, uintptr_t frameType, readMem(ctx, currentPtr, &bytecodePc); return bytecodePc; } - // aot get native pc + case FrameType::FASTJIT_FUNCTION_FRAME: + case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: { + currentPtr -= FASTJITFunctionFrame::GetTypeOffset(); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + // return returnaddr case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME: - case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: { + case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: + case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME: { currentPtr -= OptimizedJSFunctionFrame::GetTypeOffset(); currentPtr += OptimizedJSFunctionFrame::GetReturnAddrOffset(); readMem(ctx, currentPtr, &bytecodePc); return bytecodePc; } - case FrameType::FASTJIT_FUNCTION_FRAME: - case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: { - currentPtr -= FASTJITFunctionFrame::GetTypeOffset(); + case FrameType::BUILTIN_FRAME: + case FrameType::BUILTIN_ENTRY_FRAME: { + currentPtr -= BuiltinFrame::GetTypeOffset(); + currentPtr += BuiltinFrame::GetReturnAddrOffset(); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + case FrameType::BUILTIN_FRAME_WITH_ARGV: + case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME: { + currentPtr -= BuiltinWithArgvFrame::GetTypeOffset(); + currentPtr += BuiltinWithArgvFrame::GetReturnAddrOffset(); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + case FrameType::BASELINE_BUILTIN_FRAME: { + currentPtr -= BaselineBuiltinFrame::GetTypeOffset(); + currentPtr += BaselineBuiltinFrame::GetReturnAddrOffset(); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + case FrameType::ASM_BRIDGE_FRAME: { + currentPtr -= AsmBridgeFrame::GetTypeOffset(); + currentPtr += AsmBridgeFrame::GetReturnAddrOffset(); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + case FrameType::LEAVE_FRAME: { + currentPtr -= OptimizedLeaveFrame::GetTypeOffset(); + currentPtr += OptimizedLeaveFrame::GetReturnAddrOffset(); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + case FrameType::LEAVE_FRAME_WITH_ARGV: { + currentPtr -= OptimizedWithArgvLeaveFrame::GetTypeOffset(); + currentPtr += OptimizedWithArgvLeaveFrame::GetReturnAddrOffset(); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + case FrameType::BUILTIN_CALL_LEAVE_FRAME: { + currentPtr -= OptimizedBuiltinLeaveFrame::GetTypeOffset(); + currentPtr += OptimizedBuiltinLeaveFrame::GetReturnAddrOffset(); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + case FrameType::OPTIMIZED_FRAME: { + currentPtr -= OptimizedFrame::GetTypeOffset(); + currentPtr += OptimizedFrame::GetReturnAddrOffset(); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + case FrameType::ASM_INTERPRETER_BRIDGE_FRAME: { + currentPtr -= AsmInterpretedBridgeFrame::GetTypeOffset(); + currentPtr += AsmInterpretedBridgeFrame::GetReturnAddrOffset(false); + readMem(ctx, currentPtr, &bytecodePc); + return bytecodePc; + } + case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME: { + currentPtr -= OptimizedJSFunctionUnfoldArgVFrame::GetTypeOffset(); + currentPtr += OptimizedJSFunctionUnfoldArgVFrame::GetReturnAddrOffset(); readMem(ctx, currentPtr, &bytecodePc); return bytecodePc; } @@ -824,12 +919,15 @@ bool ArkGetNextFrame(void *ctx, ReadMemFunc readMem, uintptr_t ¤tPtr, return true; } bool ret = false; - if (IsFunctionFrame(frameType)) { + if (IsJsFunctionFrame(frameType)) { pc = GetBytecodeOffset(ctx, readMem, frameType, currentPtr); ret = true; if (methodId != nullptr) { ret = ArkGetMethodId(ctx, readMem, frameType, currentPtr, *methodId); } + } else if (IsNativeFunctionFrame(frameType)) { + pc = GetBytecodeOffset(ctx, readMem, frameType, currentPtr); + ret = true; } uintptr_t typeOffset = 0; @@ -868,7 +966,7 @@ bool ArkGetMethodIdWithJit(ArkUnwindParam *arkUnwindParam, uintptr_t frameType, return false; } - if (IsFastJitFunctionFrame(static_cast(frameType))) { + if (IsFastJitFunctionFrame(frameType)) { uintptr_t machineCode = 0; uintptr_t functionAddr = function + JSFunction::MACHINECODE_OFFSET; arkUnwindParam->readMem(arkUnwindParam->ctx, functionAddr, &machineCode); @@ -904,12 +1002,16 @@ bool ArkGetNextFrameWithJit(ArkUnwindParam *arkUnwindParam, uintptr_t ¤tPt return true; } bool ret = false; - if (IsFunctionFrame(frameType)) { + if (IsJsFunctionFrame(frameType) || + IsFastJitFunctionFrame(frameType)) { *arkUnwindParam->pc = GetBytecodeOffset(arkUnwindParam->ctx, arkUnwindParam->readMem, frameType, currentPtr); ret = true; if (arkUnwindParam->methodId != nullptr) { ret = ArkGetMethodIdWithJit(arkUnwindParam, frameType, currentPtr); } + } else if (IsNativeFunctionFrame(frameType)) { + *arkUnwindParam->pc = GetBytecodeOffset(arkUnwindParam->ctx, arkUnwindParam->readMem, frameType, currentPtr); + ret = true; } uintptr_t typeOffset = 0; @@ -977,7 +1079,9 @@ bool StepArkWithRecordJit(ArkUnwindParam *arkUnwindParam) } else { *arkUnwindParam->fp = currentPtr; *arkUnwindParam->sp = currentPtr; - *arkUnwindParam->isJsFrame = true; + // js && jit -> true, native -> false + *arkUnwindParam->isJsFrame = IsJsFunctionFrame(frameType) || + IsFastJitFunctionFrame(frameType); } } else { LOG_ECMA(ERROR) << "ArkGetNextFrame failed, currentPtr: " << currentPtr << ", frameType: " << frameType; @@ -1009,7 +1113,8 @@ bool StepArk(void *ctx, ReadMemFunc readMem, uintptr_t *fp, uintptr_t *sp, } else { *fp = currentPtr; *sp = currentPtr; - *isJsFrame = true; + // js -> true, native -> false + *isJsFrame = IsJsFunctionFrame(frameType); } } else { LOG_ECMA(ERROR) << std::hex << "ArkGetNextFrame failed, addr: " << currentPtr; @@ -1453,7 +1558,7 @@ bool GetArkNativeFrameInfo([[maybe_unused]] int pid, [[maybe_unused]] uintptr_t if (!ReadUintptrFromAddr(pid, currentPtr, frameType, g_needCheck)) { return false; } - if (g_needCheck && IsFunctionFrame(frameType)) { + if (g_needCheck && (IsJsFunctionFrame(frameType) || IsAotFunctionFrame(frameType))) { ArkGetJsFrameDebugInfo(pid, currentPtr, frameType, JsFrameDebugInfos); } else if (ArkFrameCheck(frameType)) { currentPtr += sizeof(FrameType); diff --git a/ecmascript/dfx/stackinfo/js_stackinfo.h b/ecmascript/dfx/stackinfo/js_stackinfo.h index 5de1ae144..35cdee2e0 100644 --- a/ecmascript/dfx/stackinfo/js_stackinfo.h +++ b/ecmascript/dfx/stackinfo/js_stackinfo.h @@ -28,6 +28,16 @@ namespace panda::ecmascript { typedef bool (*ReadMemFunc)(void *ctx, uintptr_t addr, uintptr_t *val); +bool ArkFrameCheck(uintptr_t frameType); +bool IsJsFunctionFrame(uintptr_t frameType); +bool IsNativeFunctionFrame(uintptr_t frameType); +bool IsAotFunctionFrame(uintptr_t frameType); +bool IsFastJitFunctionFrame(uintptr_t frameType); +bool IsFastJitFunctionFrame(const FrameType frameType); +template +void ParseJsFrameInfo(JSPandaFile *jsPandaFile, DebugInfoExtractor *debugExtractor, + EntityId methodId, uintptr_t offset, T &jsFrame, SourceMap *sourceMap = nullptr); + static constexpr uint16_t URL_MAX = 1024; static constexpr uint16_t FUNCTIONNAME_MAX = 1024; diff --git a/ecmascript/frames.h b/ecmascript/frames.h index 30f65e339..7143736a9 100644 --- a/ecmascript/frames.h +++ b/ecmascript/frames.h @@ -197,6 +197,11 @@ public: return GetOffset(Index::PrevFpIndex)>(isArch32); } + static size_t GetReturnAddrOffset(bool isArch32 = false) + { + return GetOffset(Index::ReturnAddrIndex)>(isArch32); + } + static size_t ComputeReservedSize(size_t slotSize) { size_t slotOffset = static_cast(Index::PrevFpIndex) - static_cast(Index::TypeIndex); @@ -270,6 +275,11 @@ public: return GetOffset(Index::PrevFpIndex)>(isArch32); } + static size_t GetReturnAddrOffset(bool isArch32 = false) + { + return GetOffset(Index::ReturnAddrIndex)>(isArch32); + } + static size_t ComputeReservedSize(size_t slotSize) { size_t slotOffset = static_cast(Index::PrevFpIndex) - static_cast(Index::TypeIndex); @@ -327,6 +337,11 @@ public: return GetOffset(Index::PrevFpIndex)>(isArch32); } + static size_t GetReturnAddrOffset(bool isArch32 = false) + { + return GetOffset(Index::ReturnAddrIndex)>(isArch32); + } + uintptr_t GetCallSiteSp() const { return ToUintPtr(this) + sizeof(AsmBridgeFrame); @@ -394,6 +409,11 @@ public: return GetOffset(Index::PrevFpIndex)>(isArch32); } + static size_t GetReturnAddrOffset(bool isArch32 = false) + { + return GetOffset(Index::ReturnAddrIndex)>(isArch32); + } + FrameType GetType() const { return type; @@ -1342,6 +1362,11 @@ struct OptimizedLeaveFrame { return MEMBER_OFFSET(OptimizedLeaveFrame, callsiteFp); } + static size_t GetReturnAddrOffset() + { + return MEMBER_OFFSET(OptimizedLeaveFrame, returnAddr); + } + void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const; }; @@ -1398,6 +1423,11 @@ struct OptimizedWithArgvLeaveFrame { return MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, callsiteFp); } + static size_t GetReturnAddrOffset() + { + return MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, returnAddr); + } + void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const; }; @@ -1458,6 +1488,11 @@ public: return MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, callsiteFp); } + static size_t GetReturnAddrOffset() + { + return MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, returnAddr); + } + static size_t GetFunctionOffset() { return MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, argc) + 1; @@ -1593,6 +1628,11 @@ struct BuiltinFrame : public base::AlignedStruct(Index::PrevFpIndex)>(isArch32); } + static size_t GetReturnAddrOffset(bool isArch32 = false) + { + return GetOffset(Index::ReturnAddrIndex)>(isArch32); + } + void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const; alignas(EAS) FrameType type; @@ -1689,6 +1729,11 @@ struct BuiltinWithArgvFrame : public base::AlignedStruct(Index::PrevFpIndex)>(isArch32); } + static size_t GetReturnAddrOffset(bool isArch32 = false) + { + return GetOffset(Index::ReturnAddrIndex)>(isArch32); + } + void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const; // argv(... this, new.target, function) // numargs diff --git a/ecmascript/jspandafile/js_pandafile_manager.cpp b/ecmascript/jspandafile/js_pandafile_manager.cpp index 64d9f446e..f1f7974be 100644 --- a/ecmascript/jspandafile/js_pandafile_manager.cpp +++ b/ecmascript/jspandafile/js_pandafile_manager.cpp @@ -155,6 +155,11 @@ std::shared_ptr JSPandaFileManager::LoadJSPandaFile(JSThread *threa auto pf = panda_file::OpenPandaFileFromMemory(buffer, size); #else CString tag = ModulePathHelper::ParseFileNameToVMAName(filename); + constexpr size_t PR_SET_VMA_ANON_NAME_MAX_LEN = 80; + constexpr size_t ANON_FLAG_LEN = 7; // [anon:] + if (tag.length() > PR_SET_VMA_ANON_NAME_MAX_LEN - ANON_FLAG_LEN) { + tag = CString(ModulePathHelper::VMA_NAME_ARKTS_CODE); + } auto pf = panda_file::OpenPandaFileFromMemory(buffer, size, tag.c_str()); #endif if (pf == nullptr) { -- Gitee From 27a4033cbc65604c29bac94e7c231e950f8cc9ac Mon Sep 17 00:00:00 2001 From: zhangyinlu Date: Tue, 9 Jul 2024 16:05:37 +0800 Subject: [PATCH 06/12] =?UTF-8?q?[pgo]=20onHeap=E4=B8=8EnotOnHeap=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E6=9C=AA=E7=BB=B4=E6=8A=A4proto=E9=93=BE=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IABOX4 Description:替换hclass需要维护proto链,对未维护proto链的场景进行修复 Signed-off-by: zhangyinlu Change-Id: Ifcc642099a1f40d29728cf7274d1a063518e185f --- ecmascript/base/typed_array_helper.cpp | 6 ++++++ ecmascript/js_typed_array.cpp | 8 +++++++- test/aottest/pgo_on_heap/pgo_on_heap.ts | 13 +++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ecmascript/base/typed_array_helper.cpp b/ecmascript/base/typed_array_helper.cpp index df1df17b1..eaeec7098 100644 --- a/ecmascript/base/typed_array_helper.cpp +++ b/ecmascript/base/typed_array_helper.cpp @@ -179,6 +179,9 @@ JSHandle TypedArrayHelper::AllocateTypedArrayBufferGetEcmaVM()->GetFactory()->NewByteArray(arrayLength, elementSize).GetTaggedValue()); JSHandle onHeapHclass = TypedArrayHelper::GetOnHeapHclassFromType( thread, JSHandle(obj), arrayType); +#if ECMASCRIPT_ENABLE_IC + JSHClass::NotifyHclassChanged(thread, JSHandle(thread, obj->GetJSHClass()), onHeapHclass); +#endif TaggedObject::Cast(*obj)->SynchronizedSetClass(thread, *onHeapHclass); // notOnHeap->onHeap } RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, exception); @@ -233,6 +236,9 @@ JSHandle TypedArrayHelper::AllocateTypedArrayBuffer onHeapHclass = TypedArrayHelper::GetSharedOnHeapHclassFromType( thread, JSHandle(obj), arrayType); +#if ECMASCRIPT_ENABLE_IC + JSHClass::NotifyHclassChanged(thread, JSHandle(thread, obj->GetJSHClass()), onHeapHclass); +#endif TaggedObject::Cast(*obj)->SynchronizedSetClass(thread, *onHeapHclass); // notOnHeap->onHeap } RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, exception); diff --git a/ecmascript/js_typed_array.cpp b/ecmascript/js_typed_array.cpp index 645466be2..4220e54a4 100644 --- a/ecmascript/js_typed_array.cpp +++ b/ecmascript/js_typed_array.cpp @@ -618,7 +618,7 @@ bool JSTypedArray::IntegerIndexedElementSet(JSThread *thread, const JSHandle(thread, JSTaggedValue::ToNumber(thread, value)); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); } - + JSHandle typedarrayObj(typedarray); JSTaggedValue buffer = typedarrayObj->GetViewedArrayBufferOrByteArray(); JSHandle indexHandle(thread, index); @@ -774,6 +774,9 @@ JSTaggedValue JSTypedArray::GetOffHeapBuffer(JSThread *thread, JSHandle notOnHeapHclass = TypedArrayHelper::GetNotOnHeapHclassFromType( thread, typedArray, arrayType); +#if ECMASCRIPT_ENABLE_IC + JSHClass::NotifyHclassChanged(thread, JSHandle(thread, typedArray->GetJSHClass()), notOnHeapHclass); +#endif TaggedObject::Cast(*typedArray)->SynchronizedSetClass(thread, *notOnHeapHclass); // onHeap->notOnHeap return arrayBuffer.GetTaggedValue(); @@ -803,6 +806,9 @@ JSTaggedValue JSSharedTypedArray::GetSharedOffHeapBuffer(JSThread *thread, JSHan DataViewType arrayType = JSTypedArray::GetTypeFromName(thread, typeName); JSHandle notOnHeapHclass = TypedArrayHelper::GetSharedNotOnHeapHclassFromType( thread, typedArray, arrayType); +#if ECMASCRIPT_ENABLE_IC + JSHClass::NotifyHclassChanged(thread, JSHandle(thread, typedArray->GetJSHClass()), notOnHeapHclass); +#endif TaggedObject::Cast(*typedArray)->SynchronizedSetClass(thread, *notOnHeapHclass); // onHeap->notOnHeap return arrayBuffer.GetTaggedValue(); diff --git a/test/aottest/pgo_on_heap/pgo_on_heap.ts b/test/aottest/pgo_on_heap/pgo_on_heap.ts index 20691c6a7..6c0b53a4e 100644 --- a/test/aottest/pgo_on_heap/pgo_on_heap.ts +++ b/test/aottest/pgo_on_heap/pgo_on_heap.ts @@ -60,3 +60,16 @@ function baz(ta: Uint32Array | Float64Array) { baz(ta0); baz(ta1); +function foo2() { + for (let v0 = 0; v0 < 5; v0++) { + function f1(a2, a3, a4) { + const v6 = new BigUint64Array(a2); + const v8 = new Uint8ClampedArray(); + const t13 = v8.__proto__; + t13.__proto__ = v6; + return v6; + } + f1(f1()); + } +} +foo2() -- Gitee From c88cf8a20f8bef28ebf652f4cb7dbc6c8aa0d377 Mon Sep 17 00:00:00 2001 From: yangxiaoshuai2022 Date: Tue, 9 Jul 2024 16:31:30 +0800 Subject: [PATCH 07/12] Fix warning of long function Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IABQFC Signed-off-by: yangxiaoshuai2022 --- ecmascript/napi/dfx_jsnapi.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/ecmascript/napi/dfx_jsnapi.cpp b/ecmascript/napi/dfx_jsnapi.cpp index 4d326b6c4..28c0e67e8 100644 --- a/ecmascript/napi/dfx_jsnapi.cpp +++ b/ecmascript/napi/dfx_jsnapi.cpp @@ -168,12 +168,8 @@ void DFXJSNApi::DumpHeapSnapshotWithVm([[maybe_unused]] const EcmaVM *vm, #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT) #if defined(ENABLE_DUMP_IN_FAULTLOG) uv_loop_t *loop = reinterpret_cast(vm->GetLoop()); - if (loop == nullptr) { - LOG_ECMA(ERROR) << "loop nullptr"; - return; - } - if (uv_loop_alive(loop) == 0) { - LOG_ECMA(ERROR) << "uv_loop_alive dead"; + if (loop == nullptr || uv_loop_alive(loop) == 0) { + LOG_ECMA(ERROR) << "loop nullptr or uv_loop_alive dead"; return; } struct DumpForSnapShotStruct *dumpStruct = new DumpForSnapShotStruct(); @@ -197,12 +193,8 @@ void DFXJSNApi::DumpHeapSnapshotWithVm([[maybe_unused]] const EcmaVM *vm, ret = uv_queue_work(loop, work, [](uv_work_t *) {}, [](uv_work_t *work, int32_t) { struct DumpForSnapShotStruct *dump = static_cast(work->data); DFXJSNApi::GetHeapPrepare(dump->vm); - DumpSnapShotOption dumpOption; - dumpOption.dumpFormat = dump->dumpFormat; - dumpOption.isVmMode = dump->isVmMode; - dumpOption.isPrivate = dump->isPrivate; - dumpOption.captureNumericValue = dump->captureNumericValue; - dumpOption.isFullGC = dump->isFullGC; + DumpSnapShotOption dumpOption = { dump->dumpFormat, dump->isVmMode, dump->isPrivate, + dump->captureNumericValue, dump->isFullGC }; DumpHeapSnapshot(dump->vm, dumpOption); delete dump; delete work; -- Gitee From 0d113ff65b1fe1d4ec140f2a34455420d3ca305b Mon Sep 17 00:00:00 2001 From: hanweiqi Date: Mon, 8 Jul 2024 15:53:27 +0800 Subject: [PATCH 08/12] Add testcase of heap_snapshot.cpp Add testcase of GenerateNodeName(include error types and some commopn types); Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IABDTI Signed-off-by: hanweiqi --- ecmascript/dfx/hprof/tests/heap_dump_test.cpp | 111 +++++++++++++++++- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/ecmascript/dfx/hprof/tests/heap_dump_test.cpp b/ecmascript/dfx/hprof/tests/heap_dump_test.cpp index eb6f89b3a..fa865283d 100644 --- a/ecmascript/dfx/hprof/tests/heap_dump_test.cpp +++ b/ecmascript/dfx/hprof/tests/heap_dump_test.cpp @@ -13,15 +13,17 @@ * limitations under the License. */ -#include "ecmascript/tests/test_helper.h" -#include "ecmascript/jspandafile/js_pandafile_manager.h" -#include "ecmascript/napi/include/jsnapi.h" #include "ecmascript/dfx/hprof/heap_snapshot.h" #include "ecmascript/dfx/hprof/heap_profiler.h" #include "ecmascript/dfx/hprof/heap_root_visitor.h" +#include "ecmascript/global_env.h" +#include "ecmascript/jspandafile/js_pandafile_manager.h" +#include "ecmascript/napi/include/jsnapi.h" +#include "ecmascript/tests/test_helper.h" namespace panda::test { using namespace panda::ecmascript; +using ErrorType = base::ErrorType; class HeapDumpTest : public testing::Test { public: @@ -65,6 +67,21 @@ public: return heapProfile->GetIdCount(); } + bool MatchHeapDumpString(const std::string &filePath, std::string targetStr) + { + std::string line; + std::ifstream inputStream(filePath); + std::size_t lineNum = 0; + while (getline(inputStream, line)) { + lineNum = line.find(targetStr); + if (lineNum != line.npos) { + return true; + } + } + GTEST_LOG_(INFO) << "_______________" << targetStr << std::to_string(lineNum) <<"_______________ not found"; + return false; // Lost the Line + } + private: EcmaVM *instance {nullptr}; }; @@ -239,4 +256,92 @@ HWTEST_F_L0(HeapDumpTest, TestHeapDumpFunctionUrl) ASSERT_TRUE(strMatched); } +HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName1) +{ + JSHandle env = thread_->GetEcmaVM()->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm_->GetFactory(); + HeapDumpTestHelper tester(ecmaVm_); + + // TAGGED_ARRAY + factory->NewTaggedArray(10); + // LEXICAL_ENV + factory->NewLexicalEnv(10); + // CONSTANT_POOL + factory->NewConstantPool(10); + // PROFILE_TYPE_INFO + factory->NewProfileTypeInfo(10); + // TAGGED_DICTIONARY + factory->NewDictionaryArray(10); + // AOT_LITERAL_INFO + factory->NewAOTLiteralInfo(10); + // VTABLE + factory->NewVTable(10); + // COW_TAGGED_ARRAY + factory->NewCOWTaggedArray(10); + // HCLASS + JSHandle proto = env->GetFunctionPrototype(); + factory->NewEcmaHClass(JSHClass::SIZE, JSType::HCLASS, proto); + // LINKED_NODE + JSHandle linkedNode(thread_, JSTaggedValue::Hole()); + factory->NewLinkedNode(1, JSHandle(thread_, JSTaggedValue::Hole()), + JSHandle(thread_, JSTaggedValue::Hole()), linkedNode); + // JS_NATIVE_POINTER + auto newData = ecmaVm_->GetNativeAreaAllocator()->AllocateBuffer(8); + factory->NewJSNativePointer(newData); + + tester.GenerateSnapShot("testGenerateNodeName_1.heapsnapshot"); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalArray[")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"LexicalEnv[")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalConstantPool[")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalProfileTypeInfo[")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalDict[")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalAOTLiteralInfo[")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalVTable[")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"ArkInternalCOWArray[")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"HiddenClass(NonMovable)")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"LinkedNode\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "\"JSNativePointer\"")); + // Test Not Found + ASSERT_TRUE(!tester.MatchHeapDumpString("testGenerateNodeName_1.heapsnapshot", "*#@failed case")); +} + +HWTEST_F_L0(HeapDumpTest, TestHeapDumpGenerateNodeName2) +{ + ObjectFactory *factory = ecmaVm_->GetFactory(); + HeapDumpTestHelper tester(ecmaVm_); + + // JS_ERROR + JSHandle handleMessage(thread_, EcmaStringAccessor::CreateEmptyString(ecmaVm_)); + factory->NewJSError(ErrorType::ERROR, handleMessage); + // JS_EVAL_ERROR + factory->NewJSError(ErrorType::EVAL_ERROR, handleMessage); + // JS_RANGE_ERROR + factory->NewJSError(ErrorType::RANGE_ERROR, handleMessage); + // JS_TYPE_ERROR + factory->NewJSError(ErrorType::TYPE_ERROR, handleMessage); + // JS_AGGREGATE_ERROR + factory->NewJSAggregateError(); + // JS_REFERENCE_ERROR + factory->NewJSError(ErrorType::REFERENCE_ERROR, handleMessage); + // JS_URI_ERROR + factory->NewJSError(ErrorType::URI_ERROR, handleMessage); + // JS_SYNTAX_ERROR + factory->NewJSError(ErrorType::SYNTAX_ERROR, handleMessage); + // JS_OOM_ERROR + factory->NewJSError(ErrorType::OOM_ERROR, handleMessage); + // JS_TERMINATION_ERROR + factory->NewJSError(ErrorType::TERMINATION_ERROR, handleMessage); + + tester.GenerateSnapShot("testGenerateNodeName_2.heapsnapshot"); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Error\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Eval Error\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Range Error\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Type Error\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Aggregate Error\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Reference Error\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Uri Error\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Syntax Error\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"OutOfMemory Error\"")); + ASSERT_TRUE(tester.MatchHeapDumpString("testGenerateNodeName_2.heapsnapshot", "\"Termination Error\"")); } +} \ No newline at end of file -- Gitee From d58a7ca8f7192dc9ba8d9b389af3fa162c756dd3 Mon Sep 17 00:00:00 2001 From: yangxiaoshuai2022 Date: Tue, 9 Jul 2024 16:58:38 +0800 Subject: [PATCH 09/12] Fix the warning of long function Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IABQI5 Signed-off-by: yangxiaoshuai2022 --- ecmascript/dfx/hprof/tests/heap_tracker_first_test.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ecmascript/dfx/hprof/tests/heap_tracker_first_test.cpp b/ecmascript/dfx/hprof/tests/heap_tracker_first_test.cpp index 02b4f6860..80b577c69 100644 --- a/ecmascript/dfx/hprof/tests/heap_tracker_first_test.cpp +++ b/ecmascript/dfx/hprof/tests/heap_tracker_first_test.cpp @@ -247,13 +247,8 @@ HWTEST_F_L0(HeapTrackerTest, DumpHeapSnapshot) outputString.clear(); FileStream stream(fileName.c_str()); - TestProgress testProgress; - DumpSnapShotOption dumpOption; - dumpOption.dumpFormat = DumpFormat::JSON; - dumpOption.isVmMode = true; - dumpOption.isPrivate = true; - dumpOption.captureNumericValue = false; - heapProfile->DumpHeapSnapshot(&stream, dumpOption, &testProgress); + DumpSnapShotOption dumpOption = { DumpFormat::JSON, true, true }; + heapProfile->DumpHeapSnapshot(&stream, dumpOption); HeapProfilerInterface::Destroy(instance); // Check -- Gitee From e64a85a0174338e17e40e006f58fbc4079b760c4 Mon Sep 17 00:00:00 2001 From: Sandee Date: Thu, 11 Jul 2024 09:25:59 +0800 Subject: [PATCH 10/12] Fix bug of float32 array Issue: https://gitee.com/openharmony/arkui_napi/issues/IAC20P Signed-off-by: sandee --- ecmascript/napi/include/jsnapi_expo.h | 3 ++- ecmascript/napi/jsnapi_expo.cpp | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ecmascript/napi/include/jsnapi_expo.h b/ecmascript/napi/include/jsnapi_expo.h index ff33753f1..d8bd18253 100644 --- a/ecmascript/napi/include/jsnapi_expo.h +++ b/ecmascript/napi/include/jsnapi_expo.h @@ -468,7 +468,8 @@ public: bool IsJSSharedUint16Array(const EcmaVM *vm); bool IsJSSharedInt32Array(const EcmaVM *vm); bool IsJSSharedUint32Array(const EcmaVM *vm); - + bool IsJSSharedFloat32Array(const EcmaVM *vm); + bool IsGeneratorObject(const EcmaVM *vm); bool IsJSPrimitiveSymbol(const EcmaVM *vm); diff --git a/ecmascript/napi/jsnapi_expo.cpp b/ecmascript/napi/jsnapi_expo.cpp index 5cca80805..ad355c3ec 100644 --- a/ecmascript/napi/jsnapi_expo.cpp +++ b/ecmascript/napi/jsnapi_expo.cpp @@ -755,6 +755,11 @@ bool JSValueRef::IsJSSharedInt32Array([[maybe_unused]] const EcmaVM *vm) return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedInt32Array(); } +bool JSValueRef::IsJSSharedFloat32Array([[maybe_unused]] const EcmaVM *vm) +{ + return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedFloat32Array(); +} + bool JSValueRef::IsJSSharedUint32Array([[maybe_unused]] const EcmaVM *vm) { return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedUint32Array(); -- Gitee From b9f272d5470737ec1e8976fa42a5a50bd020b882 Mon Sep 17 00:00:00 2001 From: zhanheng Date: Mon, 8 Jul 2024 15:44:47 +0800 Subject: [PATCH 11/12] fix fillidmap Issue: IABD8M Signed-off-by: z00522183 Change-Id: Ifb7b33d03cc0be67762a94e1e123f9e1bc179bdd --- ecmascript/dfx/hprof/heap_profiler.cpp | 44 ++++++++------------------ ecmascript/dfx/hprof/heap_profiler.h | 21 ++++++------ ecmascript/dfx/hprof/heap_snapshot.cpp | 18 +++++------ ecmascript/dfx/hprof/heap_snapshot.h | 27 +++++++--------- 4 files changed, 44 insertions(+), 66 deletions(-) diff --git a/ecmascript/dfx/hprof/heap_profiler.cpp b/ecmascript/dfx/hprof/heap_profiler.cpp index 9f76ab05a..a3e1b37c1 100644 --- a/ecmascript/dfx/hprof/heap_profiler.cpp +++ b/ecmascript/dfx/hprof/heap_profiler.cpp @@ -44,7 +44,7 @@ static pid_t ForkBySyscall(void) #endif } -std::pair EntryIdMap::FindId(JSTaggedType addr) +std::pair EntryIdMap::FindId(JSTaggedType addr) { auto it = idMap_.find(addr); if (it == idMap_.end()) { @@ -54,7 +54,7 @@ std::pair EntryIdMap::FindId(JSTaggedType addr) } } -bool EntryIdMap::InsertId(JSTaggedType addr, uint32_t id) +bool EntryIdMap::InsertId(JSTaggedType addr, NodeId id) { auto it = idMap_.find(addr); if (it == idMap_.end()) { @@ -82,7 +82,7 @@ bool EntryIdMap::Move(JSTaggedType oldAddr, JSTaggedType forwardAddr) } auto it = idMap_.find(oldAddr); if (it != idMap_.end()) { - uint32_t id = it->second; + NodeId id = it->second; idMap_.erase(it); idMap_[forwardAddr] = id; return true; @@ -96,7 +96,7 @@ void EntryIdMap::UpdateEntryIdMap(HeapSnapshot *snapshot) LOG_ECMA(FATAL) << "EntryIdMap::UpdateEntryIdMap:snapshot is nullptr"; } auto nodes = snapshot->GetNodes(); - CUnorderedMap newIdMap; + CUnorderedMap newIdMap; for (auto node : *nodes) { auto addr = node->GetAddress(); auto it = idMap_.find(addr); @@ -221,45 +221,27 @@ void HeapProfiler::FillIdMap() // Iterate SharedHeap Object SharedHeap* sHeap = SharedHeap::GetInstance(); if (sHeap != nullptr) { - sHeap->IterateOverObjects([newEntryIdMap](TaggedObject *obj) { + sHeap->IterateOverObjects([newEntryIdMap, this](TaggedObject *obj) { JSTaggedType addr = ((JSTaggedValue)obj).GetRawData(); - auto [idExist, sequenceId] = newEntryIdMap->FindId(addr); - if (!idExist) { - newEntryIdMap->InsertId(addr, sequenceId); - } + auto [idExist, sequenceId] = entryIdMap_->FindId(addr); + newEntryIdMap->InsertId(addr, sequenceId); }); } // Iterate LocalHeap Object auto heap = vm_->GetHeap(); if (heap != nullptr) { - heap->IterateOverObjects([newEntryIdMap](TaggedObject *obj) { + heap->IterateOverObjects([newEntryIdMap, this](TaggedObject *obj) { JSTaggedType addr = ((JSTaggedValue)obj).GetRawData(); - auto [idExist, sequenceId] = newEntryIdMap->FindId(addr); - if (!idExist) { - newEntryIdMap->InsertId(addr, sequenceId); - } + auto [idExist, sequenceId] = entryIdMap_->FindId(addr); + newEntryIdMap->InsertId(addr, sequenceId); }); } // copy entryIdMap - CUnorderedMap* idMap = entryIdMap_->GetIdMap(); - CUnorderedMap* newIdMap = newEntryIdMap->GetIdMap(); - if (entryIdMap_->GetIdCount() == 0) { - *idMap = *newIdMap; - entryIdMap_->SetId(newEntryIdMap->GetId()); - } else { - CUnorderedMap tempIdMap; - for (auto it : *newIdMap) { - auto addr = it.first; - auto newIt = idMap->find(addr); - if (newIt != idMap->end()) { - tempIdMap.emplace(addr, newIt->second); - } - } - idMap->clear(); - *idMap = tempIdMap; - } + CUnorderedMap* idMap = entryIdMap_->GetIdMap(); + CUnorderedMap* newIdMap = newEntryIdMap->GetIdMap(); + *idMap = *newIdMap; GetChunk()->Delete(newEntryIdMap); } diff --git a/ecmascript/dfx/hprof/heap_profiler.h b/ecmascript/dfx/hprof/heap_profiler.h index 9517a118c..6622f3437 100644 --- a/ecmascript/dfx/hprof/heap_profiler.h +++ b/ecmascript/dfx/hprof/heap_profiler.h @@ -29,6 +29,7 @@ namespace panda::ecmascript { class HeapSnapshot; class EcmaVM; +using NodeId = uint64_t; class EntryIdMap { public: @@ -37,18 +38,18 @@ public: NO_COPY_SEMANTIC(EntryIdMap); NO_MOVE_SEMANTIC(EntryIdMap); - static constexpr uint32_t SEQ_STEP = 2; - std::pair FindId(JSTaggedType addr); - bool InsertId(JSTaggedType addr, uint32_t id); + static constexpr uint64_t SEQ_STEP = 2; + std::pair FindId(JSTaggedType addr); + bool InsertId(JSTaggedType addr, NodeId id); bool EraseId(JSTaggedType addr); bool Move(JSTaggedType oldAddr, JSTaggedType forwardAddr); void UpdateEntryIdMap(HeapSnapshot *snapshot); - uint32_t GetNextId() + NodeId GetNextId() { nextId_ += SEQ_STEP; return nextId_ - SEQ_STEP; } - uint32_t GetLastId() + NodeId GetLastId() { return nextId_ - SEQ_STEP; } @@ -56,22 +57,22 @@ public: { return idMap_.size(); } - CUnorderedMap* GetIdMap() + CUnorderedMap* GetIdMap() { return &idMap_; } - uint32_t GetId() + NodeId GetId() { return nextId_; } - void SetId(uint32_t id) + void SetId(NodeId id) { nextId_ = id; } private: - uint32_t nextId_ {3U}; // 1 Reversed for SyntheticRoot - CUnorderedMap idMap_ {}; + NodeId nextId_ {3U}; // 1 Reversed for SyntheticRoot + CUnorderedMap idMap_ {}; }; class HeapProfiler : public HeapProfilerInterface { diff --git a/ecmascript/dfx/hprof/heap_snapshot.cpp b/ecmascript/dfx/hprof/heap_snapshot.cpp index 1305a6674..2516f8ab7 100644 --- a/ecmascript/dfx/hprof/heap_snapshot.cpp +++ b/ecmascript/dfx/hprof/heap_snapshot.cpp @@ -50,7 +50,7 @@ CString *HeapSnapshot::GetArrayString(TaggedArray *array, const CString &as) return GetString(arrayName); // String type was handled singly, see#GenerateStringNode } -Node *Node::NewNode(Chunk *chunk, size_t id, size_t index, const CString *name, NodeType type, size_t size, +Node *Node::NewNode(Chunk *chunk, NodeId id, size_t index, const CString *name, NodeType type, size_t size, size_t nativeSize, JSTaggedType entry, bool isLive) { auto node = chunk->New(id, index, name, type, size, nativeSize, 0, entry, isLive); @@ -61,9 +61,9 @@ Node *Node::NewNode(Chunk *chunk, size_t id, size_t index, const CString *name, return node; } -Edge *Edge::NewEdge(Chunk *chunk, uint32_t id, EdgeType type, Node *from, Node *to, CString *name) +Edge *Edge::NewEdge(Chunk *chunk, EdgeType type, Node *from, Node *to, CString *name) { - auto edge = chunk->New(id, type, from, to, name); + auto edge = chunk->New(type, from, to, name); if (UNLIKELY(edge == nullptr)) { LOG_FULL(FATAL) << "internal allocator failed"; UNREACHABLE(); @@ -71,9 +71,9 @@ Edge *Edge::NewEdge(Chunk *chunk, uint32_t id, EdgeType type, Node *from, Node * return edge; } -Edge *Edge::NewEdge(Chunk *chunk, uint32_t id, EdgeType type, Node *from, Node *to, uint32_t index) +Edge *Edge::NewEdge(Chunk *chunk, EdgeType type, Node *from, Node *to, uint32_t index) { - auto edge = chunk->New(id, type, from, to, index); + auto edge = chunk->New(type, from, to, index); if (UNLIKELY(edge == nullptr)) { LOG_FULL(FATAL) << "internal allocator failed"; UNREACHABLE(); @@ -692,7 +692,7 @@ Node *HeapSnapshot::HandleObjectNode(JSTaggedValue &entry, size_t &size, bool &i return node; } -Node *HeapSnapshot::HandleBaseClassNode(size_t size, bool idExist, unsigned int &sequenceId, +Node *HeapSnapshot::HandleBaseClassNode(size_t size, bool idExist, NodeId &sequenceId, TaggedObject* obj, JSTaggedType &addr) { size_t selfSize = (size != 0) ? size : obj->GetClass()->SizeFromJSHClass(obj); @@ -1087,8 +1087,8 @@ void HeapSnapshot::FillEdges(bool isSimplify) } if (entryTo != nullptr) { Edge *edge = (it.type_ == Reference::ReferenceType::ELEMENT) ? - Edge::NewEdge(chunk_, edgeCount_, type, entryFrom, entryTo, it.index_) : - Edge::NewEdge(chunk_, edgeCount_, type, entryFrom, entryTo, GetString(it.name_)); + Edge::NewEdge(chunk_, type, entryFrom, entryTo, it.index_) : + Edge::NewEdge(chunk_, type, entryFrom, entryTo, GetString(it.name_)); RenameFunction(it.name_, entryFrom, entryTo); InsertEdgeUnique(edge); (*iter)->IncEdgeCount(); // Update Node's edgeCount_ here @@ -1199,7 +1199,7 @@ void HeapSnapshot::AddSyntheticRoot() } \ values.insert(valueTo); \ Edge *edge = Edge::NewEdge(chunk_, \ - edgeCount_, EdgeType::SHORTCUT, syntheticRoot, rootNode, GetString("-subroot-")); \ + EdgeType::SHORTCUT, syntheticRoot, rootNode, GetString("-subroot-")); \ InsertEdgeAt(edgeOffset, edge); \ edgeOffset++; \ syntheticRoot->IncEdgeCount(); \ diff --git a/ecmascript/dfx/hprof/heap_snapshot.h b/ecmascript/dfx/hprof/heap_snapshot.h index dc06597fa..66ccabfc1 100644 --- a/ecmascript/dfx/hprof/heap_snapshot.h +++ b/ecmascript/dfx/hprof/heap_snapshot.h @@ -59,7 +59,7 @@ enum class EdgeType { CONTEXT, ELEMENT, PROPERTY, INTERNAL, HIDDEN, SHORTCUT, WE class Node { public: - Node(uint32_t id, uint32_t index, const CString *name, NodeType type, size_t size, size_t nativeSize, + Node(NodeId id, uint32_t index, const CString *name, NodeType type, size_t size, size_t nativeSize, uint32_t traceId, JSTaggedType address, bool isLive = true) : id_(id), index_(index), @@ -72,7 +72,7 @@ public: isLive_(isLive) { } - uint32_t GetId() const + NodeId GetId() const { return id_; } @@ -147,7 +147,7 @@ public: { traceId_ = traceId; } - static Node *NewNode(Chunk *chunk, size_t id, size_t index, const CString *name, NodeType type, size_t size, + static Node *NewNode(Chunk *chunk, NodeId id, size_t index, const CString *name, NodeType type, size_t size, size_t nativeSize, JSTaggedType entry, bool isLive = true); template static JSTaggedType NewAddress(T *addr) @@ -158,7 +158,7 @@ public: ~Node() = default; private: - uint32_t id_ {0}; // Range from 1 + NodeId id_ {0}; // Range from 1 uint32_t index_ {0}; const CString *name_ {nullptr}; NodeType type_ {NodeType::DEFAULT}; @@ -172,14 +172,10 @@ private: class Edge { public: - Edge(uint32_t id, EdgeType type, Node *from, Node *to, CString *name) - : id_(id), edgeType_(type), from_(from), to_(to), name_(name) {} - Edge(uint32_t id, EdgeType type, Node *from, Node *to, uint32_t index) - : id_(id), edgeType_(type), from_(from), to_(to), index_(index) {} - uint32_t GetId() const - { - return id_; - } + Edge(EdgeType type, Node *from, Node *to, CString *name) + : edgeType_(type), from_(from), to_(to), name_(name) {} + Edge(EdgeType type, Node *from, Node *to, uint32_t index) + : edgeType_(type), from_(from), to_(to), index_(index) {} EdgeType GetType() const { return edgeType_; @@ -215,13 +211,12 @@ public: { to_ = node; } - static Edge *NewEdge(Chunk *chunk, uint32_t id, EdgeType type, Node *from, Node *to, CString *name); - static Edge *NewEdge(Chunk *chunk, uint32_t id, EdgeType type, Node *from, Node *to, uint32_t index); + static Edge *NewEdge(Chunk *chunk, EdgeType type, Node *from, Node *to, CString *name); + static Edge *NewEdge(Chunk *chunk, EdgeType type, Node *from, Node *to, uint32_t index); static constexpr int EDGE_FIELD_COUNT = 3; ~Edge() = default; private: - uint32_t id_ {-1U}; EdgeType edgeType_ {EdgeType::DEFAULT}; Node *from_ {nullptr}; Node *to_ {nullptr}; @@ -503,7 +498,7 @@ private: Node *HandleStringNode(JSTaggedValue &entry, size_t &size, bool &isInFinish); Node *HandleFunctionNode(JSTaggedValue &entry, size_t &size, bool &isInFinish); Node *HandleObjectNode(JSTaggedValue &entry, size_t &size, bool &isInFinish); - Node *HandleBaseClassNode(size_t size, bool idExist, unsigned int &sequenceId, + Node *HandleBaseClassNode(size_t size, bool idExist, NodeId &sequenceId, TaggedObject* obj, JSTaggedType &addr); CString GeneratePrimitiveNameString(JSTaggedValue &entry); Node *GeneratePrivateStringNode(size_t size); -- Gitee From 9d333105a762adbbc69866efb17cdb155b293d5a Mon Sep 17 00:00:00 2001 From: zhangyukun8 Date: Sat, 13 Jul 2024 18:21:17 +0800 Subject: [PATCH 12/12] Add function info for arm64 Signed-off-by: zhangyukun8 Change-Id: Icc07f50897d27d91999dbec940d9585ff2e94a1e --- .../codegen/maple/litecg_ir_builder.cpp | 67 ++++++++++------ .../codegen/maple/litecg_ir_builder.h | 4 +- .../include/cg/aarch64/aarch64_proepilog.h | 4 +- .../src/cg/aarch64/aarch64_proepilog.cpp | 80 ++++++++++++++++++- .../maple/maple_ir/include/mir_function.h | 32 ++++++++ ecmascript/frames.h | 13 +++ 6 files changed, 170 insertions(+), 30 deletions(-) diff --git a/ecmascript/compiler/codegen/maple/litecg_ir_builder.cpp b/ecmascript/compiler/codegen/maple/litecg_ir_builder.cpp index c4f15aa04..5fac9ec54 100644 --- a/ecmascript/compiler/codegen/maple/litecg_ir_builder.cpp +++ b/ecmascript/compiler/codegen/maple/litecg_ir_builder.cpp @@ -596,8 +596,8 @@ void LiteCGIRBuilder::AssistGenPrologue(const size_t reservedSlotsSize, FrameTyp { lmirBuilder_->SetFuncFrameResverdSlot(reservedSlotsSize); if (circuit_->IsOsr()) { - SaveFrameTypeOnFrame(methodLiteral_->IsFastCall() ? FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME : - frameType); + auto osrFrameType = methodLiteral_->IsFastCall() ? FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME : frameType; + SaveFrameTypeOnFrame(function, osrFrameType); return; } auto ArgList = circuit_->GetArgRoot(); @@ -614,8 +614,8 @@ void LiteCGIRBuilder::AssistGenPrologue(const size_t reservedSlotsSize, FrameTyp } if (argth == funcIndex) { SaveByteCodePcOnOptJSFuncFrame(value); - SaveJSFuncOnOptJSFuncFrame(value); - SaveFrameTypeOnFrame(frameType); + SaveJSFuncOnOptJSFuncFrame(function, value, funcIndex); + SaveFrameTypeOnFrame(function, frameType); } } } @@ -631,13 +631,14 @@ void LiteCGIRBuilder::GenPrologue(maple::litecg::Function &function) if (frameType == FrameType::OPTIMIZED_FRAME) { reservedSlotsSize = OptimizedFrame::ComputeReservedSize(slotSize_); lmirBuilder_->SetFuncFrameResverdSlot(reservedSlotsSize); - SaveFrameTypeOnFrame(frameType); + SaveFrameTypeOnFrame(function, frameType); } else if (frameType == FrameType::OPTIMIZED_JS_FUNCTION_FRAME) { reservedSlotsSize = OptimizedJSFunctionFrame::ComputeReservedJSFuncOffset(slotSize_); lmirBuilder_->SetFuncFrameResverdSlot(reservedSlotsSize); if (circuit_->IsOsr()) { - SaveFrameTypeOnFrame(methodLiteral_->IsFastCall() ? FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME : - frameType); + auto osrFrameType = methodLiteral_->IsFastCall() ? FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME + : frameType; + SaveFrameTypeOnFrame(function, osrFrameType); return; } auto ArgList = circuit_->GetArgRoot(); @@ -653,8 +654,8 @@ void LiteCGIRBuilder::GenPrologue(maple::litecg::Function &function) funcIndex = static_cast(CommonArgIdx::FUNC); } if (argth == funcIndex) { - SaveJSFuncOnOptJSFuncFrame(value); - SaveFrameTypeOnFrame(frameType); + SaveJSFuncOnOptJSFuncFrame(function, value, funcIndex); + SaveFrameTypeOnFrame(function, frameType); } } } else if (frameType == FrameType::FASTJIT_FUNCTION_FRAME) { @@ -696,30 +697,44 @@ void LiteCGIRBuilder::SaveByteCodePcOnOptJSFuncFrame(maple::litecg::Var &value) lmirBuilder_->AppendStmt(GetFirstBB(), stmt); } -void LiteCGIRBuilder::SaveJSFuncOnOptJSFuncFrame(maple::litecg::Var &value) +void LiteCGIRBuilder::SaveJSFuncOnOptJSFuncFrame(maple::litecg::Function &function, maple::litecg::Var &value, + int funcIndex) { ASSERT(IsOptimizedJSFunction()); - Expr fpAddr = CallingFp(false); - Expr frameAddr = lmirBuilder_->Cvt(fpAddr.GetType(), lmirBuilder_->i64Type, fpAddr); - size_t reservedOffset = 0; - if (circuit_->GetFrameType() == FrameType::OPTIMIZED_JS_FUNCTION_FRAME) { - reservedOffset = OptimizedJSFunctionFrame::ComputeReservedJSFuncOffset(slotSize_); + if (compCfg_->IsAArch64()) { + auto frameType = circuit_->GetFrameType(); + if (frameType == FrameType::OPTIMIZED_JS_FUNCTION_FRAME) { + function.SetFuncInfo(OptimizedJSFunctionFrame::GetFunctionToFpDelta(), true, funcIndex); + } else if (frameType == FrameType::FASTJIT_FUNCTION_FRAME) { + function.SetFuncInfo(FASTJITFunctionFrame::GetFunctionToFpDelta(), true, funcIndex); + } } else { - reservedOffset = FASTJITFunctionFrame::ComputeReservedJSFuncOffset(slotSize_); + Expr fpAddr = CallingFp(false); + Expr frameAddr = lmirBuilder_->Cvt(fpAddr.GetType(), lmirBuilder_->i64Type, fpAddr); + size_t reservedOffset = 0; + if (circuit_->GetFrameType() == FrameType::OPTIMIZED_JS_FUNCTION_FRAME) { + reservedOffset = OptimizedJSFunctionFrame::ComputeReservedJSFuncOffset(slotSize_); + } else { + reservedOffset = FASTJITFunctionFrame::ComputeReservedJSFuncOffset(slotSize_); + } + + Expr frameJSFuncSlotAddr = + lmirBuilder_->Sub(frameAddr.GetType(), frameAddr, + lmirBuilder_->ConstVal(lmirBuilder_->CreateIntConst(slotType_, reservedOffset))); + Expr jsFuncAddr = + lmirBuilder_->Cvt(frameJSFuncSlotAddr.GetType(), lmirBuilder_->CreatePtrType(slotType_), frameJSFuncSlotAddr); + Expr jsFuncValue = lmirBuilder_->Cvt(lmirBuilder_->i64PtrType, slotType_, lmirBuilder_->GenExprFromVar(value)); + auto &stmt = lmirBuilder_->Iassign(jsFuncValue, jsFuncAddr, jsFuncAddr.GetType()); + lmirBuilder_->AppendStmt(GetFirstBB(), stmt); } - - Expr frameJSFuncSlotAddr = - lmirBuilder_->Sub(frameAddr.GetType(), frameAddr, - lmirBuilder_->ConstVal(lmirBuilder_->CreateIntConst(slotType_, reservedOffset))); - Expr jsFuncAddr = - lmirBuilder_->Cvt(frameJSFuncSlotAddr.GetType(), lmirBuilder_->CreatePtrType(slotType_), frameJSFuncSlotAddr); - Expr jsFuncValue = lmirBuilder_->Cvt(lmirBuilder_->i64PtrType, slotType_, lmirBuilder_->GenExprFromVar(value)); - auto &stmt = lmirBuilder_->Iassign(jsFuncValue, jsFuncAddr, jsFuncAddr.GetType()); - lmirBuilder_->AppendStmt(GetFirstBB(), stmt); } -void LiteCGIRBuilder::SaveFrameTypeOnFrame(FrameType frameType) +void LiteCGIRBuilder::SaveFrameTypeOnFrame(maple::litecg::Function &function, FrameType frameType) { + if (compCfg_->IsAArch64()) { + function.SetFrameTypeInfo(FRAME_TYPE_TO_FP_DELTA, true, static_cast(frameType)); + return; + } Expr fpAddr = CallingFp(false); Expr frameAddr = lmirBuilder_->Cvt(fpAddr.GetType(), lmirBuilder_->i64Type, fpAddr); Expr frameJSFuncSlotAddr = lmirBuilder_->Sub( diff --git a/ecmascript/compiler/codegen/maple/litecg_ir_builder.h b/ecmascript/compiler/codegen/maple/litecg_ir_builder.h index cfb23e906..6273a49eb 100644 --- a/ecmascript/compiler/codegen/maple/litecg_ir_builder.h +++ b/ecmascript/compiler/codegen/maple/litecg_ir_builder.h @@ -207,8 +207,8 @@ private: void GenPrologue(maple::litecg::Function &function); void AssistGenPrologue(const size_t reservedSlotsSize, FrameType frameType, maple::litecg::Function &function); void SaveByteCodePcOnOptJSFuncFrame(maple::litecg::Var &value); - void SaveJSFuncOnOptJSFuncFrame(maple::litecg::Var &value); - void SaveFrameTypeOnFrame(FrameType frameType); + void SaveJSFuncOnOptJSFuncFrame(maple::litecg::Function &function, maple::litecg::Var &value, int funcIndex); + void SaveFrameTypeOnFrame(maple::litecg::Function &function, FrameType frameType); bool IsInterpreted() const; bool IsBaselineBuiltin() const; void AddFunc(); diff --git a/ecmascript/compiler/codegen/maple/maple_be/include/cg/aarch64/aarch64_proepilog.h b/ecmascript/compiler/codegen/maple/maple_be/include/cg/aarch64/aarch64_proepilog.h index a46ebb132..fdd2220ab 100644 --- a/ecmascript/compiler/codegen/maple/maple_be/include/cg/aarch64/aarch64_proepilog.h +++ b/ecmascript/compiler/codegen/maple/maple_be/include/cg/aarch64/aarch64_proepilog.h @@ -73,7 +73,9 @@ private: void GeneratePushUnnamedVarargRegs(); void AppendInstructionStackCheck(AArch64reg reg, RegType rty, int32 offset); void GenerateProlog(BB &bb); - + void GenerateSave(); + void GenerateFrameTypeSave(SaveInfo &frameInfo, int32 stackSize, int64 fpToSpDistance); + void GenerateFunctionSave(SaveInfo &funcInfo, int32 stackSize, int64 fpToSpDistance); void GenerateRet(BB &bb); bool TestPredsOfRetBB(const BB &exitBB); void AppendInstructionDeallocateCallFrame(AArch64reg reg0, AArch64reg reg1, RegType rty); diff --git a/ecmascript/compiler/codegen/maple/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/ecmascript/compiler/codegen/maple/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 89a5eef0f..e7f56468e 100644 --- a/ecmascript/compiler/codegen/maple/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/ecmascript/compiler/codegen/maple/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -559,6 +559,84 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg } } +void AArch64GenProEpilog::GenerateFrameTypeSave(SaveInfo& frameTypeInfo, int32 stackSize, int64 fpToSpDistance) { + if (!frameTypeInfo.shouldSave) { + return; + } + auto &aarchCGFunc = static_cast(cgFunc); + //mov + auto &x10Opnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(R10, k64BitSize, kRegTyInt); + auto immOpnd = &aarchCGFunc.CreateImmOperand(frameTypeInfo.idx, k64BitSize, true); + aarchCGFunc.SelectCopyImm(x10Opnd, *immOpnd, PTY_i64); + // store + Operand *o1 = aarchCGFunc.CreateStackMemOpnd(RSP, static_cast(frameTypeInfo.offset) + fpToSpDistance, GetPointerBitSize()); + MemOperand *mem = static_cast(o1); + uint32 dataSize = GetPointerBitSize(); + if (mem->GetMemVaryType() == kNotVary && aarchCGFunc.IsImmediateOffsetOutOfRange(*mem, dataSize)) { + o1 = &aarchCGFunc.SplitOffsetWithAddInstruction(*mem, dataSize, R16); + } + + Insn &pushInsn = cgFunc.GetInsnBuilder()->BuildInsn(MOP_xstr, x10Opnd, *o1); + AppendInstructionTo(pushInsn, cgFunc); +} + +void AArch64GenProEpilog::GenerateFunctionSave(SaveInfo& funcInfo, int32 stackSize, int64 fpToSpDistance) { + if (!funcInfo.shouldSave) { + return; + } + auto &aarchCGFunc = static_cast(cgFunc); + auto &mirFunc = aarchCGFunc.GetFunction(); + CCLocInfo ploc; + CCImpl &parmlocator = *aarchCGFunc.GetOrCreateLocator(CCImpl::GetCallConvKind(aarchCGFunc.GetFunction())); + auto &x10Opnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(R10, k64BitSize, kRegTyInt); + for (size_t i = 0; i < mirFunc.GetFormalCount(); ++i) { + MIRType *ty = mirFunc.GetNthParamType(i); + parmlocator.LocateNextParm(*ty, ploc, (i == 0), mirFunc.GetMIRFuncType()); + if (i != funcInfo.idx) { + continue; + } + if (ploc.reg0 == kRinvalid) { + Operand* o1 = aarchCGFunc.CreateStackMemOpnd(RSP, ploc.memOffset + stackSize, k64BitSize); + uint32 dataSize = GetPointerBitSize(); + if (ploc.memOffset + stackSize > kStpLdpImm64UpperBound) { + o1 = SplitStpLdpOffsetForCalleeSavedWithAddInstruction(cgFunc, static_cast(*o1), dataSize, R16); + } + Insn &ldrInsn = cgFunc.GetInsnBuilder()->BuildInsn(MOP_xldr, x10Opnd, *o1); + AppendInstructionTo(ldrInsn, cgFunc); + } else { + auto &funcOpnd = + aarchCGFunc.GetOrCreatePhysicalRegisterOperand((AArch64reg)ploc.GetReg0(), k64BitSize, kRegTyInt); + aarchCGFunc.SelectCopy(x10Opnd, ploc.GetPrimTypeOfReg0(), funcOpnd, ploc.GetPrimTypeOfReg0()); + } + } + Operand *o2 = aarchCGFunc.CreateStackMemOpnd(RSP, static_cast(funcInfo.offset) + fpToSpDistance, GetPointerBitSize()); + MemOperand *mem2 = static_cast(o2); + uint32 dataSize = GetPointerBitSize(); + if (mem2->GetMemVaryType() == kNotVary && aarchCGFunc.IsImmediateOffsetOutOfRange(*mem2, dataSize)) { + o2 = &aarchCGFunc.SplitOffsetWithAddInstruction(*mem2, dataSize, R16); + } + Insn &pushInsn2 = cgFunc.GetInsnBuilder()->BuildInsn(MOP_xstr, x10Opnd, *o2); + AppendInstructionTo(pushInsn2, cgFunc); +} + +void AArch64GenProEpilog::GenerateSave() +{ + + auto &aarchCGFunc = static_cast(cgFunc); + auto &mirFunc = aarchCGFunc.GetFunction(); + auto &frameTypeInfo = mirFunc.GetFrameTypeInfo(); + auto &funcInfo = mirFunc.GetFuncInfo(); + + std::cout << "frameType: " << frameTypeInfo.offset << " " << frameTypeInfo.shouldSave << " " << frameTypeInfo.idx << "\n"; + std::cout << "funcInfo: " << funcInfo.offset << " " << funcInfo.shouldSave << " " << funcInfo.idx << "\n"; + + int32 stackFrameSize = + static_cast(static_cast(cgFunc.GetMemlayout())->RealStackFrameSize()); + int64 fpToSpDistance = cgFunc.GetMemlayout()->SizeOfArgsToStackPass() + cgFunc.GetFunction().GetFrameReseverdSlot(); + GenerateFrameTypeSave(frameTypeInfo, stackFrameSize, fpToSpDistance); + GenerateFunctionSave(funcInfo, stackFrameSize, fpToSpDistance); +} + /* * From AArch64 Reference Manual * C1.3.3 Load/Store Addressing Mode @@ -597,7 +675,7 @@ void AArch64GenProEpilog::GeneratePushRegs() } else { AppendInstructionAllocateCallFrameDebug(R29, RLR, kRegTyInt); } - + GenerateSave(); if (useFP) { if (currCG->GenerateVerboseCG()) { cgFunc.GetCurBB()->AppendInsn(aarchCGFunc.CreateCommentInsn("copy SP to FP")); diff --git a/ecmascript/compiler/codegen/maple/maple_ir/include/mir_function.h b/ecmascript/compiler/codegen/maple/maple_ir/include/mir_function.h index b327a3e30..73ffa9ce7 100644 --- a/ecmascript/compiler/codegen/maple/maple_ir/include/mir_function.h +++ b/ecmascript/compiler/codegen/maple/maple_ir/include/mir_function.h @@ -33,6 +33,13 @@ namespace maple { enum PointerAttr : uint32_t { kPointerUndeiced = 0x1, kPointerNull = 0x2, kPointerNoNull = 0x3 }; +struct SaveInfo +{ + int offset; + bool shouldSave; + int idx; +}; + enum FuncAttrProp : uint32_t { kNoThrowException = 0x1, kNoRetNewlyAllocObj = 0x2, @@ -160,6 +167,29 @@ public: funcType->SetRetTyIdx(tyidx); } + void SetFrameTypeInfo(int offset, bool shouldSave, int idx) + { + frameTypeInfo.offset = offset; + frameTypeInfo.shouldSave = shouldSave; + frameTypeInfo.idx = idx; + } + + void SetFuncInfo(int offset, bool shouldSave, int idx) + { + funcIdxInfo.offset = offset; + funcIdxInfo.shouldSave = shouldSave; + funcIdxInfo.idx = idx; + } + + SaveInfo &GetFrameTypeInfo() { + return frameTypeInfo; + } + + SaveInfo &GetFuncInfo() { + return funcIdxInfo; + } + + const MIRType *GetClassType() const; TyIdx GetClassTyIdx() const { @@ -1657,6 +1687,8 @@ private: MemReferenceTable *memReferenceTable = nullptr; void DumpFlavorLoweredThanMmpl() const; MIRFuncType *ReconstructFormals(const std::vector &symbols, bool clearOldArgs); + SaveInfo frameTypeInfo; + SaveInfo funcIdxInfo; }; } // namespace maple #endif // MAPLE_IR_INCLUDE_MIR_FUNCTION_H diff --git a/ecmascript/frames.h b/ecmascript/frames.h index 7143736a9..bffac4844 100644 --- a/ecmascript/frames.h +++ b/ecmascript/frames.h @@ -32,6 +32,7 @@ namespace kungfu { }; static constexpr int64_t BASELINEJIT_PC_FLAG = static_cast(std::numeric_limits::max()); +static constexpr int64_t FRAME_TYPE_TO_FP_DELTA = -sizeof(uintptr_t); // Here list all scenarios of calling between Runtime/CInterpreter/ASMInterpreter/AOTCompiler/CBuiltin/ASMBuitlin. // Please note that the "[]" means a must frame while "<>" means an optional frame. Each case is from top to down. @@ -633,6 +634,12 @@ public: return slotSize * slotOffset; } + static int GetFunctionToFpDelta() + { + int slotOffset = static_cast(Index::JSFuncIndex) - static_cast(Index::TypeIndex); + return slotOffset * sizeof(uintptr_t) + FRAME_TYPE_TO_FP_DELTA; + } + FrameType GetType() const { return type; @@ -1865,6 +1872,12 @@ public: return slotSize * slotOffset; } + static int GetFunctionToFpDelta() + { + int slotOffset = static_cast(Index::JSFuncIndex) - static_cast(Index::TypeIndex); + return slotOffset * sizeof(uintptr_t) + FRAME_TYPE_TO_FP_DELTA; + } + FrameType GetType() const { return type; -- Gitee