diff --git a/ecmascript/compiler/aot_compiler.cpp b/ecmascript/compiler/aot_compiler.cpp index a710d467f7dd314993b96b5584916a88fbd7ba51..f2516168ed12f78916e71617897067669a2737eb 100644 --- a/ecmascript/compiler/aot_compiler.cpp +++ b/ecmascript/compiler/aot_compiler.cpp @@ -119,6 +119,8 @@ int Main(const int argc, const char **argv) cPreprocessor.GeneratePGOTypes(cOptions); cPreprocessor.SnapshotInitialize(); ret = cPreprocessor.GetCompilerResult(); + const auto &fileInfos = cPreprocessor.GetAbcFileInfo(); + cPreprocessor.GenerateMethodMap(cOptions); PassOptions::Builder optionsBuilder; PassOptions passOptions = @@ -149,11 +151,13 @@ int Main(const int argc, const char **argv) cOptions.maxAotMethodSize_, cOptions.maxMethodsInModule_, profilerDecoder, - &passOptions); + &passOptions, + cPreprocessor.GetCallMethodFlagMap(), + fileInfos); bool isEnableLiteCG = runtimeOptions.IsCompilerEnableLiteCG(); AOTFileGenerator generator(&log, &logList, vm, cOptions.triple_, isEnableLiteCG); - const auto &fileInfos = cPreprocessor.GetAbcFileInfo(); + CompileValidFiles(passManager, generator, ret, fileInfos); std::string appSignature = cPreprocessor.GetMainPkgArgsAppSignature(); generator.SaveAOTFile(cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AN, appSignature); diff --git a/ecmascript/compiler/aot_compiler_preprocessor.cpp b/ecmascript/compiler/aot_compiler_preprocessor.cpp index fefd76f67c3aebef86517077da5666d4401c9b2a..700f3e960b98910db480a77144606d1c05c5b748 100644 --- a/ecmascript/compiler/aot_compiler_preprocessor.cpp +++ b/ecmascript/compiler/aot_compiler_preprocessor.cpp @@ -59,6 +59,53 @@ CompilationOptions::CompilationOptions(EcmaVM *vm, JSRuntimeOptions &runtimeOpti isEnableLexenvSpecialization_ = runtimeOptions.IsEnableLexenvSpecialization(); isEnableNativeInline_ = runtimeOptions.IsEnableNativeInline(); isEnableLoweringBuiltin_ = runtimeOptions.IsEnableLoweringBuiltin(); + + std::string optionSelectMethods = runtimeOptions.GetCompilerSelectMethods(); + std::string optionSkipMethods = runtimeOptions.GetCompilerSkipMethods(); + + if (!optionSelectMethods.empty() && !optionSkipMethods.empty()) { + LOG_COMPILER(FATAL) << + "--compiler-select-methods and --compiler-skip-methods should not be set at the same time"; + } + + if (!optionSelectMethods.empty()) { + ParseOption(optionSelectMethods, optionSelectMethods_); + } + + if (!optionSkipMethods.empty()) { + ParseOption(optionSkipMethods, optionSkipMethods_); + } +} + +std::vector CompilationOptions::SplitString(const std::string &str, const char ch) const +{ + std::vector vec {}; + std::istringstream sstr(str.c_str()); + std::string split; + while (getline(sstr, split, ch)) { + vec.emplace_back(split); + } + return vec; +} + +void CompilationOptions::ParseOption(const std::string &option, + std::map> &optionMap) const +{ + const char colon = ':'; + const char comma = ','; + std::string str = option; + size_t posColon = 0; + size_t posComma = 0; + do { + posColon = str.find_last_of(colon); + std::string methodNameList = str.substr(posColon + 1, str.size()); + std::vector methodNameVec = SplitString(methodNameList, comma); + str = str.substr(0, posColon); + posComma = str.find_last_of(comma); + std::string recordName = str.substr(posComma + 1, str.size()); + str = str.substr(0, posComma); + optionMap[recordName] = methodNameVec; + } while (posComma != std::string::npos); } bool AotCompilerPreprocessor::HandleTargetCompilerMode(CompilationOptions &cOptions) @@ -251,6 +298,100 @@ void AotCompilerPreprocessor::SnapshotInitialize() ptManager->InitAOTSnapshot(fileInfos_.size()); } +void CallMethodFlagMap::SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall) +{ + abcIdMethodIdToIsFastCall_[std::pair(fileDesc, methodOffset)] = isFastCall; +} + +bool CallMethodFlagMap::IsFastCall(CString fileDesc, uint32_t methodOffset) const +{ + if (!abcIdMethodIdToIsFastCall_.count(std::pair(fileDesc, methodOffset))) { + return false; + } + return abcIdMethodIdToIsFastCall_.at(std::pair(fileDesc, methodOffset)); +} + +void CallMethodFlagMap::SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile) +{ + abcIdMethodIdToIsAotCompile_[std::pair(fileDesc, methodOffset)] = isAotCompile; +} + +bool CallMethodFlagMap::IsAotCompile(CString fileDesc, uint32_t methodOffset) const +{ + if (!abcIdMethodIdToIsAotCompile_.count(std::pair(fileDesc, methodOffset))) { + return false; + } + return abcIdMethodIdToIsAotCompile_.at(std::pair(fileDesc, methodOffset)); +} + + +bool AotCompilerPreprocessor::FilterOption(const std::map> &optionMap, + const std::string &recordName, const std::string &methodName) const +{ + if (optionMap.empty()) { + return false; + } + + auto it = optionMap.find(recordName); + if (it == optionMap.end()) { + return false; + } + + std::vector vec = it->second; + return find(vec.begin(), vec.end(), methodName) != vec.end(); +} + +bool AotCompilerPreprocessor::IsSkipMethod(const JSPandaFile *jsPandaFile, const BCInfo &bytecodeInfo, + const CString &recordName, const MethodLiteral *methodLiteral, + const MethodPcInfo &methodPCInfo, const std::string &methodName, + CompilationOptions &cOptions) const +{ + if (methodPCInfo.methodsSize > bytecodeInfo.GetMaxMethodSize() || + !profilerDecoder_.Match(jsPandaFile, recordName, methodLiteral->GetMethodId())) { + return true; + } + + if (!cOptions.optionSelectMethods_.empty()) { + return !FilterOption(cOptions.optionSelectMethods_, ConvertToStdString(recordName), methodName); + } else if (!cOptions.optionSkipMethods_.empty()) { + return FilterOption(cOptions.optionSkipMethods_, ConvertToStdString(recordName), methodName); + } + + return false; +} + +void AotCompilerPreprocessor::GenerateMethodMap(CompilationOptions &cOptions) +{ + //for (const AbcFileInfo &fileInfo : fileInfos_) { + JSPandaFileManager *jsPandaFileManager = JSPandaFileManager::GetInstance(); + jsPandaFileManager->EnumerateNonVirtualJSPandaFiles + ([this, &cOptions] (std::shared_ptr jsPandaFilePtr) { + JSPandaFile *jsPandaFile = jsPandaFilePtr.get(); + BytecodeInfoCollector collector(vm_, jsPandaFile, profilerDecoder_, cOptions.maxAotMethodSize_, + cOptions.isEnableCollectLiteralInfo_); + BCInfo &bytecodeInfo = collector.GetBytecodeInfo(); + const auto &methodPcInfos = bytecodeInfo.GetMethodPcInfos(); + auto &methodList = bytecodeInfo.GetMethodList(); + for (auto it = methodList.begin(); it != methodList.end(); it++) { + uint32_t index = it->first; + auto &methodInfo = it->second; + auto &methodPcInfo = methodPcInfos[methodInfo.GetMethodPcInfoIndex()]; + auto methodLiteral = jsPandaFile->FindMethodLiteral(index); + auto methodId = methodLiteral->GetMethodId(); + const std::string methodName(MethodLiteral::GetMethodName(jsPandaFile, methodId)); + bool isAotcompile = !IsSkipMethod(jsPandaFile, bytecodeInfo, MethodLiteral::GetRecordName(jsPandaFile, EntityId(index)), + methodLiteral, methodPcInfo, methodName, cOptions); + bool isFastCall = methodLiteral->IsFastCall(); + CString fileDesc = jsPandaFile->GetNormalizedFileDesc(); + uint32_t offset = methodId.GetOffset(); + callMethodFlagMap_.SetIsAotCompile(fileDesc, offset, isAotcompile); + callMethodFlagMap_.SetIsFastCall(fileDesc, offset, isFastCall); + LOG_COMPILER(INFO) <<"!!!"<< fileDesc <<" "<< offset << " " << isAotcompile << " " << isFastCall; + } + return true; + }); +} + std::string AotCompilerPreprocessor::GetMainPkgArgsAppSignature() const { return GetMainPkgArgs() == nullptr ? "" : GetMainPkgArgs()->GetAppSignature(); diff --git a/ecmascript/compiler/aot_compiler_preprocessor.h b/ecmascript/compiler/aot_compiler_preprocessor.h index c278c1a79a4cf79ab774e1c0421304b222e6be91..b31dc3f2c2ae70b9cb1ed0df713e77f6eb586d73 100644 --- a/ecmascript/compiler/aot_compiler_preprocessor.h +++ b/ecmascript/compiler/aot_compiler_preprocessor.h @@ -15,6 +15,9 @@ #ifndef ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H #define ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H +#include "ecmascript/compiler/bytecode_info_collector.h" +#include "ecmascript/compiler/compiler_log.h" +#include "ecmascript/pgo_profiler/pgo_profiler_decoder.h" #include "ecmascript/compiler/pass_manager.h" #include "ecmascript/ecma_vm.h" #include "macros.h" @@ -32,9 +35,22 @@ struct AbcFileInfo { std::shared_ptr jsPandaFile_; }; +class CallMethodFlagMap { +public: + CallMethodFlagMap() {} + void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall); + bool IsFastCall(CString fileDesc, uint32_t methodOffset) const; + void SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile); + bool IsAotCompile(CString fileDesc, uint32_t methodOffset) const; +private: + std::map, bool> abcIdMethodIdToIsFastCall_ {}; + std::map, bool> abcIdMethodIdToIsAotCompile_ {}; +}; + struct CompilationOptions { explicit CompilationOptions(EcmaVM *vm, JSRuntimeOptions &runtimeOptions); - + void ParseOption(const std::string &option, std::map> &optionMap) const; + std::vector SplitString(const std::string &str, const char ch) const; std::string triple_; std::string outputFileName_; size_t optLevel_; @@ -64,6 +80,9 @@ struct CompilationOptions { bool isEnableNativeInline_; bool isEnablePGOHCRLowering_; bool isEnableLoweringBuiltin_; + std::map> optionSelectMethods_; + std::map> optionSkipMethods_; + }; class AotCompilerPreprocessor { @@ -94,6 +113,36 @@ public: void GeneratePGOTypes(const CompilationOptions &cOptions); void SnapshotInitialize(); + + bool FilterOption(const std::map> &optionMap, + const std::string &recordName, const std::string &methodName) const; + + bool IsSkipMethod(const JSPandaFile *jsPandaFile, const BCInfo &bytecodeInfo, + const CString &recordName, const MethodLiteral *methodLiteral, + const MethodPcInfo &methodPCInfo, const std::string &methodName, + CompilationOptions &cOptions) const; + + void GenerateMethodMap(CompilationOptions &cOptions); + + void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall) + { + callMethodFlagMap_.SetIsFastCall(fileDesc, methodOffset, isFastCall); + } + + bool IsFastCall(CString fileDesc, uint32_t methodOffset) + { + return callMethodFlagMap_.IsFastCall(fileDesc, methodOffset); + } + + void SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile) + { + callMethodFlagMap_.SetIsAotCompile(fileDesc, methodOffset, isAotCompile); + } + + bool GetIsAotCompile(CString fileDesc, uint32_t methodOffset) + { + return callMethodFlagMap_.IsAotCompile(fileDesc, methodOffset); + } std::string GetMainPkgArgsAppSignature() const; @@ -120,6 +169,10 @@ public: { return pkgsArgs_; } + const CallMethodFlagMap *GetCallMethodFlagMap() + { + return &callMethodFlagMap_; + } static std::string GetHelper() { @@ -145,6 +198,7 @@ private: PGOProfilerDecoder &profilerDecoder_; arg_list_t &pandaFileNames_; CVector fileInfos_; + CallMethodFlagMap callMethodFlagMap_; friend class OhosPkgArgs; }; } // namespace panda::ecmascript::kungfu diff --git a/ecmascript/compiler/gate_accessor.h b/ecmascript/compiler/gate_accessor.h index 2e3476c22e872c1441362ed576f263d717fe9734..b1f7f5ed548c2483bc3166c9003fbaa36f1369e2 100644 --- a/ecmascript/compiler/gate_accessor.h +++ b/ecmascript/compiler/gate_accessor.h @@ -599,8 +599,8 @@ public: void ReplaceHirAndDeleteIfException(GateRef hirGate, StateDepend replacement, GateRef value); bool IsLoopBackUse(GateRef gate, const UseIterator &useIt) const; - void GetOutStates(GateRef gate, std::vector& outStates) const; bool IsCreateArray(GateRef gate) const; + void GetOutStates(GateRef gate, std::vector& outStates) const; private: const GateMetaData *GetMetaData(GateRef gate) const; diff --git a/ecmascript/compiler/pass.h b/ecmascript/compiler/pass.h index 5314d58997d5786cb221cfd6b1ab08f92e2e80c8..721d31f0b10ae8e0799bbbf6cddfccc8690d67b0 100644 --- a/ecmascript/compiler/pass.h +++ b/ecmascript/compiler/pass.h @@ -67,11 +67,13 @@ public: PassData(BytecodeCircuitBuilder *builder, Circuit *circuit, PassContext *ctx, CompilerLog *log, std::string methodName, MethodInfo *methodInfo = nullptr, bool hasTypes = false, const CString &recordName = "", MethodLiteral *methodLiteral = nullptr, - uint32_t methodOffset = 0, NativeAreaAllocator *allocator = nullptr, + uint32_t methodOffset = 0, const CallMethodFlagMap *callMethodFlagMap = nullptr, + const CVector &fileInfos = CVector{}, NativeAreaAllocator *allocator = nullptr, PGOProfilerDecoder *decoder = nullptr, PassOptions *passOptions = nullptr) : builder_(builder), circuit_(circuit), ctx_(ctx), log_(log), methodName_(methodName), methodInfo_(methodInfo), hasTypes_(hasTypes), recordName_(recordName), methodLiteral_(methodLiteral), - methodOffset_(methodOffset), allocator_(allocator), decoder_(decoder), passOptions_(passOptions) + methodOffset_(methodOffset), callMethodFlagMap_(callMethodFlagMap), fileInfos_(fileInfos), + allocator_(allocator), decoder_(decoder), passOptions_(passOptions) { } @@ -182,6 +184,16 @@ public: return passOptions_; } + const CallMethodFlagMap *GetCallMethodFlagMap() const + { + return callMethodFlagMap_; + } + + const CVector &GetFileInfos() const + { + return fileInfos_; + } + bool IsTypeAbort() const { if (hasTypes_) { @@ -229,6 +241,8 @@ private: const CString &recordName_; MethodLiteral *methodLiteral_ {nullptr}; uint32_t methodOffset_; + const CallMethodFlagMap *callMethodFlagMap_ {nullptr}; + const CVector &fileInfos_; NativeAreaAllocator *allocator_ {nullptr}; PGOProfilerDecoder *decoder_ {nullptr}; PassOptions *passOptions_ {nullptr}; @@ -311,7 +325,10 @@ public: enableTypeLog, data->GetMethodName(), passOptions->EnableLoweringBuiltin(), - data->GetRecordName()); + data->GetRecordName(), + data->GetCallMethodFlagMap(), + data->GetFileInfos(), + data->GetPGOProfilerDecoder()); bool success = lowering.RunTypeBytecodeLowering(); if (!success) { data->MarkAsTypeAbort(); @@ -369,7 +386,12 @@ public: data->GetCompilerConfig(), data->GetTSManager(), &chunk, - passOptions->EnableLoweringBuiltin()); + passOptions->EnableLoweringBuiltin() + + /*data->GetPassContext()->GetEcmaVM()->GetJSThread(), + data->GetJSPandaFile(), + data->GetCallMethodFlagMap()*/ + ); visitor.AddPass(&lowering); visitor.VisitGraph(); visitor.PrintLog("TypeHCRLowering"); diff --git a/ecmascript/compiler/pass_manager.cpp b/ecmascript/compiler/pass_manager.cpp index d4e89367280948201493db6696ecdf9f6a884537..e72b71a976f423683ab7e4787ee89db9ff56c51d 100644 --- a/ecmascript/compiler/pass_manager.cpp +++ b/ecmascript/compiler/pass_manager.cpp @@ -96,7 +96,8 @@ bool JitPassManager::Compile(JSHandle &jsFunction, AOTFileGenerator } data_ = new PassData(builder_, circuit_, ctx_, log_, fullName, &methodInfo, hasTypes, recordName, - methodLiteral, methodOffset, vm_->GetNativeAreaAllocator(), decoder, passOptions_); + methodLiteral, methodOffset, nullptr, CVector {}, + vm_->GetNativeAreaAllocator(), decoder, passOptions_); PassRunner pipeline(data_); if (data_->GetMethodLiteral()->HasDebuggerStmt()) { data_->AbortCompilation(); @@ -255,7 +256,8 @@ bool PassManager::Compile(JSPandaFile *jsPandaFile, const std::string &fileName, } PassData data(&builder, &circuit, &ctx, log_, fullName, &methodInfo, hasTypes, recordName, - methodLiteral, methodOffset, vm_->GetNativeAreaAllocator(), decoder, passOptions_); + methodLiteral, methodOffset, callMethodFlagMap_, fileInfos_, + vm_->GetNativeAreaAllocator(), decoder, passOptions_); PassRunner pipeline(&data); if (data.GetMethodLiteral()->HasDebuggerStmt()) { data.AbortCompilation(); diff --git a/ecmascript/compiler/pass_manager.h b/ecmascript/compiler/pass_manager.h index ba899977fb0e393baad0e174587c5e6ebf75664c..872313bee3e110cc5050d3df8d062cb440f47841 100644 --- a/ecmascript/compiler/pass_manager.h +++ b/ecmascript/compiler/pass_manager.h @@ -16,6 +16,7 @@ #ifndef ECMASCRIPT_COMPILER_PASS_MANAGER_H #define ECMASCRIPT_COMPILER_PASS_MANAGER_H +#include "ecmascript/compiler/aot_compiler_preprocessor.h" #include "ecmascript/compiler/bytecode_info_collector.h" #include "ecmascript/compiler/compiler_log.h" #include "ecmascript/compiler/file_generators.h" @@ -32,6 +33,9 @@ class Bytecodes; class LexEnvManager; class CompilationConfig; class PassData; +class CallMethodFlagMap; +struct AbcFileInfo; + class PassContext { public: PassContext(const std::string &triple, CompilerLog *log, BytecodeInfoCollector* collector, IRModule *aotModule, @@ -136,12 +140,14 @@ class PassManager { public: explicit PassManager(EcmaVM* vm, std::string &triple, size_t optLevel, size_t relocMode, CompilerLog *log, AotMethodLogList *logList, size_t maxAotMethodSize, size_t maxMethodsInModule, - PGOProfilerDecoder &profilerDecoder, PassOptions *passOptions) + PGOProfilerDecoder &profilerDecoder, PassOptions *passOptions, + const CallMethodFlagMap *callMethodFlagMap, const CVector &fileInfos) : vm_(vm), triple_(triple), optLevel_(optLevel), relocMode_(relocMode), log_(log), logList_(logList), maxAotMethodSize_(maxAotMethodSize), maxMethodsInModule_(maxMethodsInModule), - profilerDecoder_(profilerDecoder), passOptions_(passOptions) { - enableJITLog_ = vm_->GetJSOptions().GetTraceJIT(); - }; + profilerDecoder_(profilerDecoder), passOptions_(passOptions), + callMethodFlagMap_(callMethodFlagMap), fileInfos_(fileInfos) { + enableJITLog_ = vm_->GetJSOptions().GetTraceJIT(); + }; virtual ~PassManager() = default; bool Compile(JSPandaFile *jsPandaFile, const std::string &fileName, AOTFileGenerator &generator); @@ -159,6 +165,8 @@ protected: size_t maxMethodsInModule_ {0}; PGOProfilerDecoder &profilerDecoder_; PassOptions *passOptions_ {nullptr}; + const CallMethodFlagMap *callMethodFlagMap_ {nullptr}; + const CVector &fileInfos_; bool enableJITLog_ {false}; }; @@ -167,7 +175,8 @@ public: JitPassManager(EcmaVM* vm, std::string &triple, size_t optLevel, size_t relocMode, CompilerLog *log, AotMethodLogList *logList, PGOProfilerDecoder &profilerDecoder, PassOptions *passOptions) - : PassManager(vm, triple, optLevel, relocMode, log, logList, 1, 1, profilerDecoder, passOptions) { }; + : PassManager(vm, triple, optLevel, relocMode, log, logList, 1, 1, profilerDecoder, passOptions, + nullptr, CVector {}) { }; bool Compile(JSHandle &jsFunction, AOTFileGenerator &gen); bool RunCg(); diff --git a/ecmascript/compiler/pgo_type/pgo_type_manager.h b/ecmascript/compiler/pgo_type/pgo_type_manager.h index 04e61689be9d5e340105b1ac6963759892bd9255..2cff22949c6f1ae5e64463c0dd6bddbef699c855 100644 --- a/ecmascript/compiler/pgo_type/pgo_type_manager.h +++ b/ecmascript/compiler/pgo_type/pgo_type_manager.h @@ -99,7 +99,7 @@ public: { locToElmsKindMap_.emplace(loc, kind); } - + private: // snapshot void GenHClassInfo(); diff --git a/ecmascript/compiler/profiler_stub_builder.cpp b/ecmascript/compiler/profiler_stub_builder.cpp index 1d64c5ebf7bc3dce5056f4d52d83c7574a5089f3..4a5317e9beac739e3a8a364ddef4a030d5db9ad5 100644 --- a/ecmascript/compiler/profiler_stub_builder.cpp +++ b/ecmascript/compiler/profiler_stub_builder.cpp @@ -263,7 +263,7 @@ void ProfilerStubBuilder::ProfileCall( Bind(¤tIsHotness); { Label icSlotValid(env); - Label isInt(env); + Label isHeapObject(env); Label uninitialized(env); Label updateSlot(env); @@ -272,21 +272,21 @@ void ProfilerStubBuilder::ProfileCall( Branch(Int32LessThan(slotId, length), &icSlotValid, &exit); Bind(&icSlotValid); GateRef slotValue = GetValueFromTaggedArray(profileTypeInfo, slotId); - Branch(TaggedIsInt(slotValue), &isInt, &uninitialized); - Bind(&isInt); + Branch(TaggedIsHeapObject(slotValue), &isHeapObject, &uninitialized); + Bind(&isHeapObject); { Label change(env); Label resetSlot(env); - GateRef oldSlotValue = TaggedGetInt(slotValue); - GateRef methodId = env->GetBuilder()->GetMethodId(target); - Branch(Int32Equal(oldSlotValue, TruncInt64ToInt32(methodId)), &exit, &change); + //GateRef oldSlotValue = TaggedGetInt(slotValue); + GateRef method = env->GetBuilder()->GetMethodFromFunction(target); + Branch(Int64Equal(slotValue, method), &exit, &change); Bind(&change); { - Branch(Int32Equal(oldSlotValue, Int32(0)), &exit, &resetSlot); + Branch(Int64Equal(ChangeTaggedPointerToInt64(slotValue), Int64(0)), &exit, &resetSlot); } Bind(&resetSlot); { - GateRef nonType = IntToTaggedInt(Int32(0)); + GateRef nonType = IntToTaggedInt(Int64(0)); SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, nonType); TryPreDumpInner(glue, func, profileTypeInfo); Jump(&exit); @@ -298,9 +298,9 @@ void ProfilerStubBuilder::ProfileCall( } Bind(&updateSlot); { - GateRef methodId = env->GetBuilder()->GetMethodId(target); - GateRef methodIdValue = IntToTaggedInt(TruncInt64ToInt32(methodId)); - SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, methodIdValue); + GateRef method = env->GetBuilder()->GetMethodFromFunction(target); + //GateRef methodIdValue = IntToTaggedInt(TruncInt64ToInt32(method)); + SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, method); TryPreDumpInner(glue, func, profileTypeInfo); Jump(&exit); } diff --git a/ecmascript/compiler/stub_builder.h b/ecmascript/compiler/stub_builder.h index 9b605c03db1dde73f407a1115fa50d97c11fa76a..73aaafe68a9f1606ea6a154f7f838d766edf594f 100644 --- a/ecmascript/compiler/stub_builder.h +++ b/ecmascript/compiler/stub_builder.h @@ -766,9 +766,9 @@ public: GateRef AppendSkipHole(GateRef glue, GateRef first, GateRef second, GateRef copyLength); GateRef IntToEcmaString(GateRef glue, GateRef number); + GateRef ChangeTaggedPointerToInt64(GateRef x); private: using BinaryOperation = std::function; - GateRef ChangeTaggedPointerToInt64(GateRef x); template GateRef FastAddSubAndMul(GateRef glue, GateRef left, GateRef right, ProfileOperation callback); GateRef FastIntDiv(GateRef left, GateRef right, Label *bailout, ProfileOperation callback); diff --git a/ecmascript/compiler/tests/meta_data_equal_test.cpp b/ecmascript/compiler/tests/meta_data_equal_test.cpp index a6978b9a1964f3e962296556138c15a9c979b1d8..ab3b873c25e06e3c0d5626d06ac59bf2d9ff385e 100644 --- a/ecmascript/compiler/tests/meta_data_equal_test.cpp +++ b/ecmascript/compiler/tests/meta_data_equal_test.cpp @@ -136,10 +136,10 @@ HWTEST_F_L0(MetaDataEqualTests, HCRMetaDataEqualTest) builder.SetEnvironment(&env); // JSBytecodeMetaData - auto meta = circuit.JSBytecode(0, EcmaOpcode::JEQZ_IMM8, 0, true, false); + auto meta = circuit.JSBytecode(0, EcmaOpcode::JEQZ_IMM8, 0, 0, true, false); auto gate = circuit.NewGate(meta, MachineType::I64, {Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType()); - auto meta2 = circuit.JSBytecode(0, EcmaOpcode::JEQZ_IMM8, 0, true, false); + auto meta2 = circuit.JSBytecode(0, EcmaOpcode::JEQZ_IMM8, 0, 0, true, false); auto gate2 = circuit.NewGate(meta2, MachineType::I64, {Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType()); diff --git a/ecmascript/compiler/ts_inline_lowering.cpp b/ecmascript/compiler/ts_inline_lowering.cpp index 365f7d3f1d77ffd1dedea48721fceb38dd19b8df..f5f32d75897e2bd2fa31b4f3c656d1cdcb43c9f2 100644 --- a/ecmascript/compiler/ts_inline_lowering.cpp +++ b/ecmascript/compiler/ts_inline_lowering.cpp @@ -230,7 +230,8 @@ void TSInlineLowering::InlineCall(MethodInfo &methodInfo, MethodPcInfo &methodPC PassData data(&builder, circuit_, ctx_, log, fullName, &methodInfo, hasTyps, recordName, - method, method->GetMethodId().GetOffset(), nativeAreaAllocator_, ctx_->GetPfDecoder(), passOptions_); + method, method->GetMethodId().GetOffset(), nullptr, CVector{}, + nativeAreaAllocator_, ctx_->GetPfDecoder(), passOptions_); PassRunner pipeline(&data); pipeline.RunPass(); if (builder.EnableLoopOptimization()) { diff --git a/ecmascript/compiler/type_bytecode_lowering.cpp b/ecmascript/compiler/type_bytecode_lowering.cpp index b8b213525b20accffa97ef5793c9bc5e1da9d1db..331075ef0a134b91e9e1a0ad503a30523efad4cb 100644 --- a/ecmascript/compiler/type_bytecode_lowering.cpp +++ b/ecmascript/compiler/type_bytecode_lowering.cpp @@ -21,6 +21,8 @@ #include "ecmascript/dfx/vmstat/opt_code_profiler.h" #include "ecmascript/enum_conversion.h" #include "ecmascript/js_tagged_value.h" +#include "ecmascript/jspandafile/js_pandafile.h" +#include "ecmascript/jspandafile/js_pandafile_manager.h" #include "ecmascript/jspandafile/program_object.h" #include "ecmascript/stackmap/llvm_stackmap_parser.h" @@ -447,6 +449,9 @@ void TypeBytecodeLowering::DeleteConstDataIfNoUser(GateRef gate) void TypeBytecodeLowering::LowerTypedLdObjByName(GateRef gate) { + if(acc_.GetId(gate) == 234){ + + } DISALLOW_GARBAGE_COLLECTION; LoadObjByNameTypeInfoAccessor tacc(thread_, circuit_, gate, chunk_); @@ -1250,9 +1255,9 @@ template void TypeBytecodeLowering::CheckThisCallTargetAndLowerCall(const TypeAccessor &tacc, const std::vector &args, const std::vector &argsFastCall) { - if (!tacc.FastCallFlagIsVaild()) { + /*if (!tacc.FastCallFlagIsVaild()) { return; - } + }*/ GateRef func = tacc.GetFunc(); GateRef gate = tacc.GetGate(); bool isNoGC = tacc.IsNoGC(); @@ -1292,9 +1297,9 @@ void TypeBytecodeLowering::CheckCallTargetAndLowerCall(const TypeAccessor &tacc, } else { bool isNoGC = tacc.IsNoGC(); auto op = acc_.GetOpCode(func); - if (!tacc.FastCallFlagIsVaild()) { + /*if (!tacc.FastCallFlagIsVaild()) { return; - } + }*/ if (op == OpCode::JS_BYTECODE && (acc_.GetByteCodeOpcode(func) == EcmaOpcode::DEFINEFUNC_IMM8_ID16_IMM8 || acc_.GetByteCodeOpcode(func) == EcmaOpcode::DEFINEFUNC_IMM16_ID16_IMM8)) { CheckCallTargetFromDefineFuncAndLowerCall(tacc, args, argsFastCall, isNoGC); @@ -1376,12 +1381,13 @@ void TypeBytecodeLowering::LowerTypedCall(const TypeAccessor &tacc) argsFastCall.emplace_back(builder_.Undefined()); args.emplace_back(builder_.Undefined()); } + AddProfiling(gate); CheckCallTargetAndLowerCall(tacc, args, argsFastCall); } void TypeBytecodeLowering::LowerTypedCallArg0(GateRef gate) { - CallArg0TypeInfoAccessor tacc(thread_, circuit_, gate); + CallArg0TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); if (!tacc.IsFunctionTypeKind()) { return; } @@ -1390,7 +1396,7 @@ void TypeBytecodeLowering::LowerTypedCallArg0(GateRef gate) void TypeBytecodeLowering::LowerTypedCallArg1(GateRef gate) { - CallArg1TypeInfoAccessor tacc(thread_, circuit_, gate); + CallArg1TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); GateRef func = tacc.GetFunc(); GateRef a0Value = tacc.GetValue(); GateType a0Type = tacc.GetValueGateType(); @@ -1412,7 +1418,7 @@ void TypeBytecodeLowering::LowerTypedCallArg1(GateRef gate) void TypeBytecodeLowering::LowerTypedCallArg2(GateRef gate) { - CallArg2TypeInfoAccessor tacc(thread_, circuit_, gate); + CallArg2TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); if (!tacc.IsFunctionTypeKind()) { return; } @@ -1421,7 +1427,7 @@ void TypeBytecodeLowering::LowerTypedCallArg2(GateRef gate) void TypeBytecodeLowering::LowerTypedCallArg3(GateRef gate) { - CallArg3TypeInfoAccessor tacc(thread_, circuit_, gate); + CallArg3TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); if (!tacc.IsFunctionTypeKind()) { return; } @@ -1430,7 +1436,7 @@ void TypeBytecodeLowering::LowerTypedCallArg3(GateRef gate) void TypeBytecodeLowering::LowerTypedCallrange(GateRef gate) { - CallRangeTypeInfoAccessor tacc(thread_, circuit_, gate); + CallRangeTypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); if (!tacc.IsFunctionTypeKind()) { return; } @@ -1440,7 +1446,7 @@ void TypeBytecodeLowering::LowerTypedCallrange(GateRef gate) bool TypeBytecodeLowering::IsLoadVtable(GateRef func) { auto op = acc_.GetOpCode(func); - if (op != OpCode::LOAD_PROPERTY || !acc_.IsVtable(func)) { + if (op != OpCode::LOAD_PROPERTY) { return false; } return true; @@ -1497,12 +1503,39 @@ void TypeBytecodeLowering::LowerTypedThisCall(const TypeAccessor &tacc) argsFastCall.emplace_back(builder_.Undefined()); args.emplace_back(builder_.Undefined()); } + AddProfiling(gate); CheckThisCallTargetAndLowerCall(tacc, args, argsFastCall); } +const JSPandaFile* TypeBytecodeLowering::FindPandaFileByFileDesc(CString fileDesc) +{ + for (const auto &fileInfo:fileInfos_) { + if (fileInfo.jsPandaFile_->GetNormalizedFileDesc() == fileDesc) { + return fileInfo.jsPandaFile_.get(); + } + } + UNREACHABLE(); +} + +const JSPandaFile* TypeBytecodeLowering::GetCalleePandaFile(GateRef gate) +{ + auto profileType = acc_.TryGetPGOType(gate).GetPGOSampleType(); + bool haveProfileType = !profileType->IsNone(); + if (haveProfileType) { + auto abcId = profileType->GetProfileType().GetAbcId(); + CString fileDesc; + if (!decoder_->GetAbcNameById(abcId, fileDesc)) { + return nullptr; + } + return JSPandaFileManager::GetInstance()->FindJSPandaFileByNormalizedName(fileDesc).get(); + } + // nullptr if no pgo info + return nullptr; +} + void TypeBytecodeLowering::LowerTypedCallthis0(GateRef gate) { - CallThis0TypeInfoAccessor tacc(thread_, circuit_, gate); + CallThis0TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); BuiltinsStubCSigns::ID id = tacc.TryGetBuiltinId(BuiltinTypeId::ARRAY); if (id == BuiltinsStubCSigns::ID::SORT) { AddProfiling(gate); @@ -1523,7 +1556,7 @@ void TypeBytecodeLowering::LowerTypedCallthis0(GateRef gate) void TypeBytecodeLowering::LowerTypedCallthis1(GateRef gate) { - CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate); + CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); BuiltinsStubCSigns::ID id = tacc.TryGetBuiltinId(BuiltinTypeId::MATH); if (id == BuiltinsStubCSigns::ID::NONE) { id = tacc.TryGetBuiltinId(BuiltinTypeId::JSON); @@ -1545,7 +1578,7 @@ void TypeBytecodeLowering::LowerTypedCallthis1(GateRef gate) void TypeBytecodeLowering::LowerTypedCallthis2(GateRef gate) { - CallThis2TypeInfoAccessor tacc(thread_, circuit_, gate); + CallThis2TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); if (!tacc.CanOptimizeAsFastCall()) { return; } @@ -1554,7 +1587,7 @@ void TypeBytecodeLowering::LowerTypedCallthis2(GateRef gate) void TypeBytecodeLowering::LowerTypedCallthis3(GateRef gate) { - CallThis3TypeInfoAccessor tacc(thread_, circuit_, gate); + CallThis3TypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); BuiltinsStubCSigns::ID id = tacc.TryGetBuiltinId(BuiltinTypeId::STRING); if (IS_TYPED_BUILTINS_ID_CALL_THIS3(id)) { AddProfiling(gate); @@ -1569,7 +1602,7 @@ void TypeBytecodeLowering::LowerTypedCallthis3(GateRef gate) void TypeBytecodeLowering::LowerTypedCallthisrange(GateRef gate) { - CallThisRangeTypeInfoAccessor tacc(thread_, circuit_, gate); + CallThisRangeTypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); if (!tacc.CanOptimizeAsFastCall()) { return; } @@ -1668,7 +1701,7 @@ void TypeBytecodeLowering::LowerTypedTypeOf(GateRef gate) void TypeBytecodeLowering::LowerGetIterator(GateRef gate) { - GetIteratorTypeInfoAccessor tacc(thread_, circuit_, gate); + GetIteratorTypeInfoAccessor tacc(thread_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_); BuiltinsStubCSigns::ID id = tacc.TryGetPGOBuiltinId(); if (id == BuiltinsStubCSigns::ID::NONE) { return; diff --git a/ecmascript/compiler/type_bytecode_lowering.h b/ecmascript/compiler/type_bytecode_lowering.h index 9b6217fdd9dcd8c7ee22a5aad940b86dcbe4a708..340ef7a66f0861920400e2f439163eae56d5dd20 100644 --- a/ecmascript/compiler/type_bytecode_lowering.h +++ b/ecmascript/compiler/type_bytecode_lowering.h @@ -17,6 +17,7 @@ #define ECMASCRIPT_COMPILER_TYPE_BYTECODE_LOWERING_H #include "ecmascript/builtin_entries.h" +#include "ecmascript/compiler/aot_compiler_preprocessor.h" #include "ecmascript/compiler/argument_accessor.h" #include "ecmascript/compiler/builtins/builtins_call_signature.h" #include "ecmascript/compiler/bytecode_circuit_builder.h" @@ -37,7 +38,10 @@ public: bool enableTypeLog, const std::string& name, bool enableLoweringBuiltin, - const CString& recordName) + const CString& recordName, + const CallMethodFlagMap* callMethodFlagMap, + const CVector &fileInfos, + PGOProfilerDecoder *decoder) : circuit_(circuit), acc_(circuit), builder_(circuit, ctx->GetCompilerConfig()), @@ -57,7 +61,10 @@ public: noCheck_(ctx->GetEcmaVM()->GetJSOptions().IsCompilerNoCheck()), thread_(ctx->GetEcmaVM()->GetJSThread()), enableLoweringBuiltin_(enableLoweringBuiltin), - recordName_(recordName) + recordName_(recordName), + callMethodFlagMap_(callMethodFlagMap), + fileInfos_(fileInfos), + decoder_(decoder) { } @@ -131,8 +138,9 @@ private: void LowerTypedLdObjByValue(GateRef gate); bool TryLowerTypedLdObjByValueForBuiltin(GateRef gate); void LowerTypedStObjByValue(GateRef gate); - void LowerTypedStOwnByValue(GateRef gate); bool TryLowerTypedStObjByValueForBuiltin(GateRef gate); + + void LowerTypedStOwnByValue(GateRef gate); void LowerTypedIsTrueOrFalse(GateRef gate, bool flag); @@ -203,6 +211,8 @@ private: BuiltinsStubCSigns::ID id, bool isThrow); void DeleteConstDataIfNoUser(GateRef gate); bool TryLowerNewBuiltinConstructor(GateRef gate); + const JSPandaFile* GetCalleePandaFile(GateRef gate); + const JSPandaFile* FindPandaFileByFileDesc(CString fileDesc); void AddProfiling(GateRef gate); @@ -237,6 +247,9 @@ private: const JSThread *thread_ {nullptr}; bool enableLoweringBuiltin_ {false}; const CString &recordName_; + const CallMethodFlagMap *callMethodFlagMap_; + const CVector &fileInfos_; + PGOProfilerDecoder *decoder_ {nullptr}; }; } // panda::ecmascript::kungfu #endif // ECMASCRIPT_COMPILER_TYPE_BYTECODE_LOWERING_H diff --git a/ecmascript/compiler/type_hcr_lowering.cpp b/ecmascript/compiler/type_hcr_lowering.cpp index 5c95c9ae67f6c5acd714f99585d48459b909f29b..f5cfbc466e3babb7b820068bf81427785523b04d 100644 --- a/ecmascript/compiler/type_hcr_lowering.cpp +++ b/ecmascript/compiler/type_hcr_lowering.cpp @@ -1367,24 +1367,24 @@ void TypeHCRLowering::LowerTypedCallBuitin(GateRef gate) void TypeHCRLowering::LowerJSCallTargetFromDefineFuncCheck(GateRef gate) { Environment env(gate, circuit_, &builder_); - auto type = acc_.GetParamGateType(gate); - if (tsManager_->IsFunctionTypeKind(type)) { + // auto type = acc_.GetParamGateType(gate); + // if (tsManager_->IsFunctionTypeKind(type)) { GateRef frameState = GetFrameState(gate); auto func = acc_.GetValueIn(gate, 0); GateRef check = builder_.JudgeAotAndFastCall(func, CircuitBuilder::JudgeMethodType::HAS_AOT); builder_.DeoptCheck(check, frameState, DeoptType::NOTJSCALLTGT); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); - } else { - LOG_COMPILER(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } + // } else { + // LOG_COMPILER(FATAL) << "this branch is unreachable"; + // UNREACHABLE(); + // } } void TypeHCRLowering::LowerJSCallTargetTypeCheck(GateRef gate) { Environment env(gate, circuit_, &builder_); - auto type = acc_.GetParamGateType(gate); - if (tsManager_->IsFunctionTypeKind(type)) { + // auto type = acc_.GetParamGateType(gate); + // if (tsManager_->IsFunctionTypeKind(type)) { ArgumentAccessor argAcc(circuit_); GateRef frameState = GetFrameState(gate); GateRef jsFunc = argAcc.GetFrameArgsIn(frameState, FrameArgIdx::FUNC); @@ -1399,17 +1399,17 @@ void TypeHCRLowering::LowerJSCallTargetTypeCheck(GateRef gate) GateRef check = builder_.BoolAnd(checkFunc, builder_.Equal(funcMethodTarget, methodTarget)); builder_.DeoptCheck(check, frameState, DeoptType::NOTJSCALLTGT); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); - } else { - LOG_COMPILER(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } + // } else { + // LOG_COMPILER(FATAL) << "this branch is unreachable"; + // UNREACHABLE(); + // } } void TypeHCRLowering::LowerJSFastCallTargetTypeCheck(GateRef gate) { Environment env(gate, circuit_, &builder_); - auto type = acc_.GetParamGateType(gate); - if (tsManager_->IsFunctionTypeKind(type)) { + // auto type = acc_.GetParamGateType(gate); + // if (tsManager_->IsFunctionTypeKind(type)) { ArgumentAccessor argAcc(circuit_); GateRef frameState = GetFrameState(gate); GateRef jsFunc = argAcc.GetFrameArgsIn(frameState, FrameArgIdx::FUNC); @@ -1423,17 +1423,17 @@ void TypeHCRLowering::LowerJSFastCallTargetTypeCheck(GateRef gate) GateRef check = builder_.BoolAnd(checkFunc, builder_.Equal(funcMethodTarget, methodTarget)); builder_.DeoptCheck(check, frameState, DeoptType::NOTJSFASTCALLTGT); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); - } else { - LOG_COMPILER(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } + // } else { + // LOG_COMPILER(FATAL) << "this branch is unreachable"; + // UNREACHABLE(); + // } } void TypeHCRLowering::LowerJSCallThisTargetTypeCheck(GateRef gate) { Environment env(gate, circuit_, &builder_); - auto type = acc_.GetParamGateType(gate); - if (tsManager_->IsFunctionTypeKind(type)) { + // auto type = acc_.GetParamGateType(gate); + // if (tsManager_->IsFunctionTypeKind(type)) { GateRef frameState = GetFrameState(gate); auto func = acc_.GetValueIn(gate, 0); GateRef isObj = builder_.TaggedIsHeapObject(func); @@ -1441,17 +1441,17 @@ void TypeHCRLowering::LowerJSCallThisTargetTypeCheck(GateRef gate) GateRef check = builder_.BoolAnd(isObj, isOptimized); builder_.DeoptCheck(check, frameState, DeoptType::NOTJSCALLTGT); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); - } else { - LOG_COMPILER(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } + // } else { + // LOG_COMPILER(FATAL) << "this branch is unreachable"; + // UNREACHABLE(); + // } } void TypeHCRLowering::LowerJSNoGCCallThisTargetTypeCheck(GateRef gate) { Environment env(gate, circuit_, &builder_); - auto type = acc_.GetParamGateType(gate); - if (tsManager_->IsFunctionTypeKind(type)) { + // auto type = acc_.GetParamGateType(gate); + // if (tsManager_->IsFunctionTypeKind(type)) { GateRef frameState = GetFrameState(gate); auto func = acc_.GetValueIn(gate, 0); GateRef isObj = builder_.TaggedIsHeapObject(func); @@ -1461,17 +1461,17 @@ void TypeHCRLowering::LowerJSNoGCCallThisTargetTypeCheck(GateRef gate) GateRef check = builder_.BoolAnd(checkOptimized, builder_.Equal(methodId, acc_.GetValueIn(gate, 1))); builder_.DeoptCheck(check, frameState, DeoptType::NOTJSCALLTGT); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); - } else { - LOG_COMPILER(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } + // } else { + // LOG_COMPILER(FATAL) << "this branch is unreachable"; + // UNREACHABLE(); + // } } void TypeHCRLowering::LowerJSFastCallThisTargetTypeCheck(GateRef gate) { Environment env(gate, circuit_, &builder_); - auto type = acc_.GetParamGateType(gate); - if (tsManager_->IsFunctionTypeKind(type)) { + // auto type = acc_.GetParamGateType(gate); + // if (tsManager_->IsFunctionTypeKind(type)) { GateRef frameState = GetFrameState(gate); auto func = acc_.GetValueIn(gate, 0); GateRef isObj = builder_.TaggedIsHeapObject(func); @@ -1479,17 +1479,17 @@ void TypeHCRLowering::LowerJSFastCallThisTargetTypeCheck(GateRef gate) GateRef check = builder_.BoolAnd(isObj, canFastCall); builder_.DeoptCheck(check, frameState, DeoptType::NOTJSFASTCALLTGT); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); - } else { - LOG_COMPILER(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } + // } else { + // LOG_COMPILER(FATAL) << "this branch is unreachable"; + // UNREACHABLE(); + // } } void TypeHCRLowering::LowerJSNoGCFastCallThisTargetTypeCheck(GateRef gate) { Environment env(gate, circuit_, &builder_); - auto type = acc_.GetParamGateType(gate); - if (tsManager_->IsFunctionTypeKind(type)) { + // auto type = acc_.GetParamGateType(gate); + // if (tsManager_->IsFunctionTypeKind(type)) { GateRef frameState = GetFrameState(gate); auto func = acc_.GetValueIn(gate, 0); GateRef isObj = builder_.TaggedIsHeapObject(func); @@ -1499,10 +1499,10 @@ void TypeHCRLowering::LowerJSNoGCFastCallThisTargetTypeCheck(GateRef gate) GateRef check = builder_.BoolAnd(checkOptimized, builder_.Equal(methodId, acc_.GetValueIn(gate, 1))); builder_.DeoptCheck(check, frameState, DeoptType::NOTJSFASTCALLTGT); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); - } else { - LOG_COMPILER(FATAL) << "this branch is unreachable"; - UNREACHABLE(); - } + // } else { + // LOG_COMPILER(FATAL) << "this branch is unreachable"; + // UNREACHABLE(); + // } } void TypeHCRLowering::LowerCallTargetCheck(GateRef gate) diff --git a/ecmascript/compiler/type_hcr_lowering.h b/ecmascript/compiler/type_hcr_lowering.h index 7751dec89edc29783a3fc0a276d68a3ae165ee53..961a058a6500434dcbccc6598bddb61080b244c7 100644 --- a/ecmascript/compiler/type_hcr_lowering.h +++ b/ecmascript/compiler/type_hcr_lowering.h @@ -20,6 +20,7 @@ #include "ecmascript/compiler/bytecode_circuit_builder.h" #include "ecmascript/compiler/circuit_builder-inl.h" #include "ecmascript/compiler/combined_pass_visitor.h" +#include "ecmascript/compiler/type_info_accessors.h" namespace panda::ecmascript::kungfu { // TypeHCRLowering Process @@ -103,14 +104,20 @@ public: CompilationConfig* cmpCfg, TSManager* tsManager, Chunk* chunk, - bool enableLoweringBuiltin) + bool enableLoweringBuiltin/*, + const JSThread *thread, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap*/) : PassVisitor(circuit, chunk, visitor), circuit_(circuit), acc_(circuit), builder_(circuit, cmpCfg), dependEntry_(circuit->GetDependRoot()), tsManager_(tsManager), - enableLoweringBuiltin_(enableLoweringBuiltin) + enableLoweringBuiltin_(enableLoweringBuiltin)/*, + thread_(thread), + jsPandaFile_(jsPandaFile), + callMethodFlagMap_(callMethodFlagMap)*/ { } @@ -249,6 +256,9 @@ private: GateRef dependEntry_; [[maybe_unused]] TSManager *tsManager_ {nullptr}; bool enableLoweringBuiltin_ {false}; + /*const JSThread *thread_ {nullptr}; + const JSPandaFile *jsPandaFile_; + const CallMethodFlagMap *callMethodFlagMap_;*/ }; } // panda::ecmascript::kungfu #endif // ECMASCRIPT_COMPILER_TYPE_HCR_LOWERING_H diff --git a/ecmascript/compiler/type_info_accessors.cpp b/ecmascript/compiler/type_info_accessors.cpp index e2482ccb8db290e9b20b75b70b2567ef42d3d859..e3ea1e6ea314d57ed206229643a3c5b2fca6300d 100644 --- a/ecmascript/compiler/type_info_accessors.cpp +++ b/ecmascript/compiler/type_info_accessors.cpp @@ -203,44 +203,56 @@ BuiltinsStubCSigns::ID CallTypeInfoAccessor::TryGetBuiltinId(BuiltinTypeId id) c return stubId; } -GetIteratorTypeInfoAccessor::GetIteratorTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallTypeInfoAccessor(thread, circuit, gate) +GetIteratorTypeInfoAccessor::GetIteratorTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { argc_ = 0; func_ = acc_.GetValueIn(gate, 0); } -CallArg0TypeInfoAccessor::CallArg0TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallTypeInfoAccessor(thread, circuit, gate) +CallArg0TypeInfoAccessor::CallArg0TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { argc_ = 0; func_ = acc_.GetValueIn(gate, 0); } -CallArg1TypeInfoAccessor::CallArg1TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallTypeInfoAccessor(thread, circuit, gate) +CallArg1TypeInfoAccessor::CallArg1TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { argc_ = 1; value_ = acc_.GetValueIn(gate, 0); func_ = acc_.GetValueIn(gate, 1); } -CallArg2TypeInfoAccessor::CallArg2TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallTypeInfoAccessor(thread, circuit, gate) +CallArg2TypeInfoAccessor::CallArg2TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { argc_ = 2; func_ = acc_.GetValueIn(gate, 2); } -CallArg3TypeInfoAccessor::CallArg3TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallTypeInfoAccessor(thread, circuit, gate) +CallArg3TypeInfoAccessor::CallArg3TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { argc_ = 3; func_ = acc_.GetValueIn(gate, 3); } -CallRangeTypeInfoAccessor::CallRangeTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallTypeInfoAccessor(thread, circuit, gate) +CallRangeTypeInfoAccessor::CallRangeTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { size_t numArgs = acc_.GetNumValueIn(gate); constexpr size_t callTargetIndex = 1; // acc @@ -250,41 +262,67 @@ CallRangeTypeInfoAccessor::CallRangeTypeInfoAccessor(const JSThread *thread, Cir bool CallThisTypeInfoAccessor::CanOptimizeAsFastCall() { - GateType funcType = acc_.GetGateType(func_); - if (!tsManager_->IsFunctionTypeKind(funcType)) { + [[maybe_unused]]GateType funcType = acc_.GetGateType(func_); + auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); + [[maybe_unused]]auto op = acc_.GetOpCode(func_); + if (!IsFunctionTypeKind()) { + return false; + } + if (!profileType->IsNone()) { + if (profileType->IsProfileTypeNone() || op != OpCode::LOAD_PROPERTY) { + return false; + } + return true; + } else { + if (!tsManager_->IsFunctionTypeKind(funcType)) { + return false; + } else if (op != OpCode::LOAD_PROPERTY || !acc_.IsVtable(func_)) { + return false; + } + return true; + } + /*if (!tsManager_->IsFunctionTypeKind(funcType)) { return false; } auto op = acc_.GetOpCode(func_); if (op != OpCode::LOAD_PROPERTY || !acc_.IsVtable(func_)) { return false; } - return true; + return true;*/ } -CallThis0TypeInfoAccessor::CallThis0TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallThisTypeInfoAccessor(thread, circuit, gate) +CallThis0TypeInfoAccessor::CallThis0TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { argc_ = 0; func_ = acc_.GetValueIn(gate, 1); } -CallThis1TypeInfoAccessor::CallThis1TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallThisTypeInfoAccessor(thread, circuit, gate) +CallThis1TypeInfoAccessor::CallThis1TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { argc_ = 1; func_ = acc_.GetValueIn(gate, 2); a0_ = acc_.GetValueIn(gate, 1); } -CallThis2TypeInfoAccessor::CallThis2TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallThisTypeInfoAccessor(thread, circuit, gate) +CallThis2TypeInfoAccessor::CallThis2TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { argc_ = 2; func_ = acc_.GetValueIn(gate, 3); } -CallThis3TypeInfoAccessor::CallThis3TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallThisTypeInfoAccessor(thread, circuit, gate) +CallThis3TypeInfoAccessor::CallThis3TypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { argc_ = 3; func_ = acc_.GetValueIn(gate, 3); @@ -293,8 +331,10 @@ CallThis3TypeInfoAccessor::CallThis3TypeInfoAccessor(const JSThread *thread, Cir a2_ = acc_.GetValueIn(gate, 3); } -CallThisRangeTypeInfoAccessor::CallThisRangeTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate) - : CallThisTypeInfoAccessor(thread, circuit, gate) +CallThisRangeTypeInfoAccessor::CallThisRangeTypeInfoAccessor(const JSThread *thread, Circuit *circuit, GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallThisTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { constexpr size_t fixedInputsNum = 1; constexpr size_t callTargetIndex = 1; // 1: acc diff --git a/ecmascript/compiler/type_info_accessors.h b/ecmascript/compiler/type_info_accessors.h index 05f53cd7db5a8e5001f6098a7d15eb0884e07e6c..762b703b75b00b8b623e4dd292bd4d7f4d4e714a 100644 --- a/ecmascript/compiler/type_info_accessors.h +++ b/ecmascript/compiler/type_info_accessors.h @@ -16,9 +16,12 @@ #ifndef ECMASCRIPT_COMPILER_TYPE_INFO_ACCESSORS_H #define ECMASCRIPT_COMPILER_TYPE_INFO_ACCESSORS_H +#include "ecmascript/compiler/aot_compiler_preprocessor.h" #include "ecmascript/compiler/argument_accessor.h" #include "ecmascript/compiler/pgo_type/pgo_type_manager.h" +#include "ecmascript/jspandafile/program_object.h" #include "ecmascript/ts_types/ts_manager.h" +#include "libpandafile/index_accessor.h" namespace panda::ecmascript::kungfu { class TypeInfoAccessor { @@ -217,10 +220,14 @@ class CallTypeInfoAccessor : public TypeInfoAccessor { public: CallTypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate) + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) : TypeInfoAccessor(thread, circuit, gate), argc_(0), - func_(Circuit::NullGate()) + func_(Circuit::NullGate()), + jsPandaFile_(jsPandaFile), + callMethodFlagMap_(callMethodFlagMap) {} NO_COPY_SEMANTIC(CallTypeInfoAccessor); NO_MOVE_SEMANTIC(CallTypeInfoAccessor); @@ -242,21 +249,51 @@ public: bool IsFunctionTypeKind() const { - return tsManager_->IsFunctionTypeKind(acc_.GetGateType(func_)); + auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); + GateType funcType = acc_.GetGateType(func_); + if (!profileType->IsNone()) { + return jsPandaFile_ != nullptr && !profileType->IsProfileTypeNone() && + profileType->GetProfileType().GetKind() == panda::ecmascript::pgo::ProfileType::Kind::MethodId && + profileType->GetProfileType().GetId() > 0; + } else { + return tsManager_->IsFunctionTypeKind(funcType); + } } - + bool IsHotnessFunc() const { + //ishotnessfunc == is aot compiled == >size + auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); + bool haveProfileType = !profileType->IsNone(); + if (haveProfileType) { + CString fileDesc = jsPandaFile_->GetNormalizedFileDesc(); + uint32_t methodId = profileType->GetProfileType().GetId(); + return callMethodFlagMap_->IsAotCompile(fileDesc, methodId); + } return tsManager_->IsHotnessFunc(GetFunctionGT()); } uint32_t GetFunctionTypeLength() const { + auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); + bool haveProfileType = !profileType->IsNone(); + if (haveProfileType) { + uint32_t methodId = profileType->GetProfileType().GetId(); + MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId); + return targetMethodLiteral->GetNumArgsWithCallField(); + } return tsManager_->GetFunctionTypeLength(GetFunctionGT()); } bool IsNoGC() const { + auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); + bool haveProfileType = !profileType->IsNone(); + if (haveProfileType) { + uint32_t methodId = profileType->GetProfileType().GetId(); + MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId); + return targetMethodLiteral->IsNoGC(); + } return tsManager_->IsNoGC(GetFunctionGT()); } @@ -267,21 +304,49 @@ public: int GetMethodIndex() const { + auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); + bool haveProfileType = !profileType->IsNone(); + if (haveProfileType) { + uint32_t methodId = profileType->GetProfileType().GetId(); + panda_file::IndexAccessor indexAccessor(*(jsPandaFile_->GetPandaFile()), + panda_file::File::EntityId(methodId)); + uint32_t cpId = static_cast(indexAccessor.GetHeaderIndex()); + JSHandle constpoolHandle(thread_, thread_->GetCurrentEcmaContext()->FindConstpool(jsPandaFile_, cpId)); + return constpoolHandle->GetMethodIndexByEntityId(panda_file::File::EntityId(methodId)); + // MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId); + // return ptManager_->GetMethodIndex(jsPandaFile_, methodId); + } return tsManager_->GetMethodIndex(GetFunctionGT()); } bool MethodOffsetIsVaild() const { - return tsManager_->MethodOffsetIsVaild(GetFunctionGT()); + auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); + //bool haveProfileType = !profileType->IsNone(); + return !profileType->IsNone() || tsManager_->MethodOffsetIsVaild(GetFunctionGT()); } bool CanFastCall() const { + auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); + bool haveProfileType = !profileType->IsNone(); + if (haveProfileType) { + CString fileDesc = jsPandaFile_->GetNormalizedFileDesc(); + uint32_t methodId = profileType->GetProfileType().GetId(); + return callMethodFlagMap_->IsAotCompile(fileDesc, methodId) && callMethodFlagMap_->IsFastCall(fileDesc, methodId); + } return tsManager_->CanFastCall(GetFunctionGT()); } uint32_t GetFuncMethodOffset() const { + auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); + bool haveProfileType = !profileType->IsNone(); + if (haveProfileType) { + uint32_t methodId = profileType->GetProfileType().GetId(); + MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId); + return targetMethodLiteral->GetMethodId().GetOffset(); + } return tsManager_->GetFuncMethodOffset(GetFunctionGT()); } @@ -297,13 +362,17 @@ protected: size_t argc_; GateRef func_; + const JSPandaFile *jsPandaFile_; + const CallMethodFlagMap *callMethodFlagMap_; }; class GetIteratorTypeInfoAccessor final : public CallTypeInfoAccessor { public: GetIteratorTypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(GetIteratorTypeInfoAccessor); NO_MOVE_SEMANTIC(GetIteratorTypeInfoAccessor); @@ -317,7 +386,9 @@ class CallArg0TypeInfoAccessor final : public CallTypeInfoAccessor { public: CallArg0TypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallArg0TypeInfoAccessor); NO_MOVE_SEMANTIC(CallArg0TypeInfoAccessor); }; @@ -326,7 +397,9 @@ class CallArg1TypeInfoAccessor final : public CallTypeInfoAccessor { public: CallArg1TypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallArg1TypeInfoAccessor); NO_MOVE_SEMANTIC(CallArg1TypeInfoAccessor); @@ -348,7 +421,9 @@ class CallArg2TypeInfoAccessor final : public CallTypeInfoAccessor { public: CallArg2TypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallArg2TypeInfoAccessor); NO_MOVE_SEMANTIC(CallArg2TypeInfoAccessor); }; @@ -357,7 +432,9 @@ class CallArg3TypeInfoAccessor final : public CallTypeInfoAccessor { public: CallArg3TypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallArg3TypeInfoAccessor); NO_MOVE_SEMANTIC(CallArg3TypeInfoAccessor); }; @@ -366,7 +443,9 @@ class CallRangeTypeInfoAccessor final : public CallTypeInfoAccessor { public: CallRangeTypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallRangeTypeInfoAccessor); NO_MOVE_SEMANTIC(CallRangeTypeInfoAccessor); }; @@ -375,8 +454,10 @@ class CallThisTypeInfoAccessor : public CallTypeInfoAccessor { public: CallThisTypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate) - : CallTypeInfoAccessor(thread, circuit, gate) + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap) + : CallTypeInfoAccessor(thread, circuit, gate, jsPandaFile, callMethodFlagMap) { thisObj_ = acc_.GetValueIn(gate, 0); } @@ -397,7 +478,9 @@ class CallThis0TypeInfoAccessor final : public CallThisTypeInfoAccessor { public: CallThis0TypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallThis0TypeInfoAccessor); NO_MOVE_SEMANTIC(CallThis0TypeInfoAccessor); }; @@ -406,7 +489,9 @@ class CallThis1TypeInfoAccessor final : public CallThisTypeInfoAccessor { public: CallThis1TypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallThis1TypeInfoAccessor); NO_MOVE_SEMANTIC(CallThis1TypeInfoAccessor); @@ -428,7 +513,9 @@ class CallThis2TypeInfoAccessor final : public CallThisTypeInfoAccessor { public: CallThis2TypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallThis2TypeInfoAccessor); NO_MOVE_SEMANTIC(CallThis2TypeInfoAccessor); }; @@ -437,7 +524,9 @@ class CallThis3TypeInfoAccessor final : public CallThisTypeInfoAccessor { public: CallThis3TypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallThis3TypeInfoAccessor); NO_MOVE_SEMANTIC(CallThis3TypeInfoAccessor); @@ -456,7 +545,9 @@ class CallThisRangeTypeInfoAccessor final : public CallThisTypeInfoAccessor { public: CallThisRangeTypeInfoAccessor(const JSThread *thread, Circuit *circuit, - GateRef gate); + GateRef gate, + const JSPandaFile *jsPandaFile, + const CallMethodFlagMap *callMethodFlagMap); NO_COPY_SEMANTIC(CallThisRangeTypeInfoAccessor); NO_MOVE_SEMANTIC(CallThisRangeTypeInfoAccessor); }; diff --git a/ecmascript/dfx/vmstat/opt_code_profiler.cpp b/ecmascript/dfx/vmstat/opt_code_profiler.cpp index 73834b0aa0988619ecdd2be94547edf430f64d94..33da48285c5fbe62c051cc121281fe8769583ddb 100644 --- a/ecmascript/dfx/vmstat/opt_code_profiler.cpp +++ b/ecmascript/dfx/vmstat/opt_code_profiler.cpp @@ -40,7 +40,7 @@ void OptCodeProfiler::PrintAndReset() LOG_ECMA(INFO) << "Runtime Statistics of optimized code path:"; static constexpr int nameRightAdjustment = 46; static constexpr int numberRightAdjustment = 15; - static constexpr int hundred = 85; + static constexpr int hundred = 100; LOG_ECMA(INFO) << std::right << std::setw(nameRightAdjustment) << "Bytecode" << std::setw(numberRightAdjustment) << "bcIndex" << std::setw(numberRightAdjustment) << "Count" @@ -113,11 +113,11 @@ void OptCodeProfiler::PrintMethodRecord(Key key, std::string methodName) static constexpr int nameRightAdjustment = 46; static constexpr int numberRightAdjustment = 15; - static constexpr int hundred = 85; + static constexpr int hundred = 100; BcRecord& bcRecord = methodIdToRecord_[key.Value()]; for (auto it = bcRecord.begin(); it != bcRecord.end(); it++) { Record record = it->second; - if (record.Count() == 0 || record.Count() < skipMaxCount_) { + if (record.Count() == 0) { break; } diff --git a/ecmascript/dfx/vmstat/opt_code_profiler.h b/ecmascript/dfx/vmstat/opt_code_profiler.h index dd38c8816b0e0112aae361bfbbfaf30b084076d3..7ccdb7f0674aa95cc6a06b2cfd8fd3e0415b312f 100644 --- a/ecmascript/dfx/vmstat/opt_code_profiler.h +++ b/ecmascript/dfx/vmstat/opt_code_profiler.h @@ -197,7 +197,7 @@ private: } int printMehodCount_ {10}; - int skipMaxCount_ {10000}; + [[maybe_unused]]int skipMaxCount_ {10000}; std::map profMap_; std::map methodIdToRecord_; std::map methodIdToName_; diff --git a/ecmascript/jspandafile/js_pandafile_manager.h b/ecmascript/jspandafile/js_pandafile_manager.h index 296ecc866c1654ce17ff7e8716eaa4e86369493a..a651e8f3a7333cad9e7cf538bcdb5443983ba99c 100644 --- a/ecmascript/jspandafile/js_pandafile_manager.h +++ b/ecmascript/jspandafile/js_pandafile_manager.h @@ -19,6 +19,7 @@ #include "ecmascript/jspandafile/js_pandafile.h" #include "ecmascript/jspandafile/panda_file_translator.h" #include "ecmascript/jspandafile/debug_info_extractor.h" +#include "ecmascript/ts_types/ts_type_table.h" #include "ecmascript/platform/mutex.h" namespace panda { @@ -75,6 +76,24 @@ public: } } + template + void EnumerateNonVirtualJSPandaFiles(Callback cb) + { + LockHolder lock(jsPandaFileLock_); + for (const auto &item : loadedJSPandaFiles_) { + if (item.first == panda::ecmascript::TSTypeTable::DEFAULT_TYPE_VIRTUAL_NAME) { + continue; + } + if (!cb(item.second.first)) { + return; + } + } + for (const auto &item : oldJSPandaFiles_) { + if (!cb(item.first)) { + return; + } + } + } std::shared_ptr FindJSPandaFileByNormalizedName(const CString &normalizedName); std::shared_ptr FindJSPandaFile(const CString &filename); std::shared_ptr FindMergedJSPandaFile(); diff --git a/ecmascript/pgo_profiler/pgo_profiler.cpp b/ecmascript/pgo_profiler/pgo_profiler.cpp index f9335af10658628ae51c9fe4df69136a166fa6e6..483e0c0b8b1eaef79663e78200e6820dadc95c2f 100644 --- a/ecmascript/pgo_profiler/pgo_profiler.cpp +++ b/ecmascript/pgo_profiler/pgo_profiler.cpp @@ -1073,12 +1073,26 @@ void PGOProfiler::DumpCall(ApEntityId abcId, const CString &recordName, EntityId uint32_t slotId, ProfileTypeInfo *profileTypeInfo) { JSTaggedValue slotValue = profileTypeInfo->Get(slotId); - if (!slotValue.IsInt()) { + ProfileType::Kind kind; + int calleeMethodId = 0; + ApEntityId calleeAbcId = 0; + if (slotValue.IsInt()) { + calleeMethodId = slotValue.GetInt(); + calleeAbcId = abcId; + ASSERT(calleeMethodId <= 0); + if (calleeMethodId == 0) { + return; + } + kind = ProfileType::Kind::BuiltinFunctionId; + } else if(slotValue.IsMethod()) { + Method *calleeMethod = Method::Cast(slotValue); + calleeMethodId = calleeMethod->GetMethodId().GetOffset(); + calleeAbcId = GetMethodAbcId(slotValue); + kind = ProfileType::Kind::MethodId; + } else { return; } - int calleeMethodId = slotValue.GetInt(); - ProfileType::Kind kind = (calleeMethodId < 0) ? ProfileType::Kind::BuiltinFunctionId : ProfileType::Kind::MethodId; - PGOSampleType type = PGOSampleType::CreateProfileType(abcId, std::abs(calleeMethodId), kind); + PGOSampleType type = PGOSampleType::CreateProfileType(calleeAbcId, std::abs(calleeMethodId), kind); ProfileType recordType = GetRecordProfileType(abcId, recordName); recordInfos_->AddCallTargetType(recordType, methodId, bcOffset, type); } @@ -1354,15 +1368,14 @@ void PGOProfiler::Reset(bool isEnable) } } -ApEntityId PGOProfiler::GetMethodAbcId(JSFunction *jsFunction) +ApEntityId PGOProfiler::GetMethodAbcId(JSTaggedValue jsMethod) { + ASSERT(jsMethod.IsMethod()); CString pfName; - auto jsMethod = jsFunction->GetMethod(); - if (jsMethod.IsMethod()) { - const auto *pf = Method::Cast(jsMethod)->GetJSPandaFile(); - if (pf != nullptr) { - pfName = pf->GetJSPandaFileDesc(); - } + + const auto *pf = Method::Cast(jsMethod)->GetJSPandaFile(); + if (pf != nullptr) { + pfName = pf->GetJSPandaFileDesc(); } ApEntityId abcId(0); if (!PGOProfilerManager::GetInstance()->GetPandaFileId(pfName, abcId) && !pfName.empty()) { @@ -1370,6 +1383,16 @@ ApEntityId PGOProfiler::GetMethodAbcId(JSFunction *jsFunction) } return abcId; } +ApEntityId PGOProfiler::GetMethodAbcId(JSFunction *jsFunction) +{ + CString pfName; + auto jsMethod = jsFunction->GetMethod(); + if (jsMethod.IsMethod()) { + return GetMethodAbcId(jsMethod); + } + LOG_ECMA(ERROR) << "Get method abc id failed. Not a method."; + UNREACHABLE(); +} ProfileType PGOProfiler::GetRecordProfileType(JSFunction *jsFunction, const CString &recordName) { diff --git a/ecmascript/pgo_profiler/pgo_profiler.h b/ecmascript/pgo_profiler/pgo_profiler.h index 2ba6a0c1937fe9b1b437d5b81e9b3b21b420682a..2ca721bc70df75d252eea8174e0ef09c9e781e5a 100644 --- a/ecmascript/pgo_profiler/pgo_profiler.h +++ b/ecmascript/pgo_profiler/pgo_profiler.h @@ -247,6 +247,7 @@ private: }; static ApEntityId GetMethodAbcId(JSFunction *jsFunction); + static ApEntityId GetMethodAbcId(JSTaggedValue jsMethod); ProfileType GetRecordProfileType(JSFunction *jsFunction, const CString &recordName); ProfileType GetRecordProfileType(ApEntityId abcId, const CString &recordName); ProfileType GetRecordProfileType(const std::shared_ptr &pf, ApEntityId abcId, diff --git a/ecmascript/pgo_profiler/types/pgo_profiler_type.h b/ecmascript/pgo_profiler/types/pgo_profiler_type.h index bc5a99ea19ef67ac10f79b6d3e23db699b38639d..402a411463ab9972fb3710289da9df4f592c2bf8 100644 --- a/ecmascript/pgo_profiler/types/pgo_profiler_type.h +++ b/ecmascript/pgo_profiler/types/pgo_profiler_type.h @@ -345,6 +345,11 @@ public: } } + bool IsProfileTypeNone() const + { + return type_.index() == 1 && GetProfileType() == ProfileType::PROFILE_TYPE_NONE; + } + bool operator<(const PGOSampleTemplate &right) const { return type_ < right.type_;