From 5d59d320e72c0408760427f8111131596bc47018 Mon Sep 17 00:00:00 2001 From: songzhengchao Date: Fri, 31 Dec 2021 15:51:09 +0800 Subject: [PATCH 1/4] 1 review code 2 visit gc ptr by patchpoint instead of pc 3 contruct frame for aot Change-Id: I98d1f8e39803ef7e1ac6c2f88e08d3254c6ef6af Signed-off-by: songzhengchao --- ecmascript/compiler/compiler_macros.h | 2 +- ecmascript/compiler/fast_stub.cpp | 18 +- ecmascript/compiler/fast_stub_define.h | 2 +- ecmascript/compiler/llvm/llvm_new.patch | 515 +++++++----------- .../compiler/llvm/llvm_stackmap_parser.cpp | 216 ++++++-- .../compiler/llvm/llvm_stackmap_parser.h | 30 +- ecmascript/compiler/llvm_codegen.cpp | 50 +- ecmascript/compiler/llvm_codegen.h | 4 +- ecmascript/compiler/llvm_ir_builder.cpp | 218 ++++++-- ecmascript/compiler/llvm_ir_builder.h | 20 +- ecmascript/compiler/stub.cpp | 12 +- ecmascript/compiler/stub.h | 7 +- ecmascript/compiler/stub_descriptor.cpp | 9 +- ecmascript/compiler/tests/stub_tests.cpp | 6 +- ecmascript/frames.h | 215 +++----- ecmascript/interpreter/frame_handler.cpp | 134 ++--- ecmascript/interpreter/frame_handler.h | 42 +- ecmascript/interpreter/interpreter-inl.h | 174 +++--- ecmascript/interpreter/interpreter.h | 18 +- ecmascript/js_thread.h | 38 +- ecmascript/mem/heap.cpp | 20 +- ecmascript/mem/heap.h | 6 +- ecmascript/runtime_trampolines.cpp | 79 +-- ecmascript/runtime_trampolines.h | 28 +- ecmascript/tests/test_helper.h | 4 +- 25 files changed, 965 insertions(+), 902 deletions(-) diff --git a/ecmascript/compiler/compiler_macros.h b/ecmascript/compiler/compiler_macros.h index d8b56cbd35..347a41f3c9 100644 --- a/ecmascript/compiler/compiler_macros.h +++ b/ecmascript/compiler/compiler_macros.h @@ -21,6 +21,6 @@ #define ECMASCRIPT_ENABLE_COMPILER_LOG 0 -#define COMPILER_LOG(level) ECMASCRIPT_ENABLE_COMPILER_LOG &&LOG_ECMA(level) +#define COMPILER_LOG(level) ECMASCRIPT_ENABLE_COMPILER_LOG && LOG_ECMA(level) #endif // ECMASCRIPT_COMPILER_MACROS_H diff --git a/ecmascript/compiler/fast_stub.cpp b/ecmascript/compiler/fast_stub.cpp index 56fa5e9c54..63624f497c 100644 --- a/ecmascript/compiler/fast_stub.cpp +++ b/ecmascript/compiler/fast_stub.cpp @@ -172,15 +172,17 @@ void FastMulGCTestStub::GenerateCircuit(const CompilationConfig *cfg) doubleX = DoubleMul(*doubleX, *doubleY); StubDescriptor *getTaggedArrayPtr = GET_STUBDESCRIPTOR(GetTaggedArrayPtrTest); GateRef ptr1 = CallRuntime(getTaggedArrayPtr, glue, GetWord64Constant(FAST_STUB_ID(GetTaggedArrayPtrTest)), { - glue - }); + glue + }); GateRef ptr2 = CallRuntime(getTaggedArrayPtr, glue, GetWord64Constant(FAST_STUB_ID(GetTaggedArrayPtrTest)), { - glue - }); - (void)ptr2; - auto value = Load(MachineType::UINT64, ptr1); - GateRef value2 = CastInt64ToFloat64(value); - doubleX = DoubleMul(*doubleX, value2); + glue + }); + auto value1 = Load(MachineType::UINT64, ptr1); + GateRef tmp = CastInt64ToFloat64(value1); + doubleX = DoubleMul(*doubleX, tmp); + auto value2 = Load(MachineType::UINT64, ptr2); + tmp = CastInt64ToFloat64(value2); + doubleX = DoubleMul(*doubleX, tmp); Return(DoubleBuildTaggedWithNoGC(*doubleX)); } #endif diff --git a/ecmascript/compiler/fast_stub_define.h b/ecmascript/compiler/fast_stub_define.h index b2cbadab47..0abef15830 100644 --- a/ecmascript/compiler/fast_stub_define.h +++ b/ecmascript/compiler/fast_stub_define.h @@ -40,7 +40,7 @@ namespace panda::ecmascript::kungfu { V(SetValueWithBarrier, 4) \ V(PropertiesSetValue, 6) \ V(TaggedArraySetValue, 6) \ - V(NewEcmaDynClass, 3) \ + V(NewEcmaDynClass, 4) \ V(UpdateLayOutAndAddTransition, 5) \ V(NoticeThroughChainAndRefreshUser, 3) \ V(DebugPrint, 1) diff --git a/ecmascript/compiler/llvm/llvm_new.patch b/ecmascript/compiler/llvm/llvm_new.patch index 1323fa9886..9ec0c64ede 100644 --- a/ecmascript/compiler/llvm/llvm_new.patch +++ b/ecmascript/compiler/llvm/llvm_new.patch @@ -47,19 +47,20 @@ index c7d4c4d7e5d..1df40696dd0 100644 virtual void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const {} diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp -index 3909b571728..c8b3c1c2928 100644 +index 3909b571728..d530c9e6c08 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp -@@ -79,6 +79,8 @@ using MBBVector = SmallVector; +@@ -79,6 +79,9 @@ using MBBVector = SmallVector; STATISTIC(NumLeafFuncWithSpills, "Number of leaf functions with CSRs"); STATISTIC(NumFuncSeen, "Number of functions seen in PEI"); +#define JS_ENTRY_FRAME_MARK 1 +#define JS_FRAME_MARK 0 ++ namespace { -@@ -878,6 +880,35 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { +@@ -878,6 +881,35 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { int64_t FixedCSEnd = Offset; unsigned MaxAlign = MFI.getMaxAlignment(); @@ -72,22 +73,22 @@ index 3909b571728..c8b3c1c2928 100644 + slotSize = 8; + } + if (MF.getFunction().hasFnAttribute("js-stub-call")) { -+ int64_t marker = 0x0; -+ MF.getFunction() -+ .getFnAttribute("js-stub-call") -+ .getValueAsString() -+ .getAsInteger(10, marker);//marker 1 break frame -+ if (marker == JS_ENTRY_FRAME_MARK) { -+ CalleeSavedFrameSize = 3 * slotSize;/* frameType + threadSP */ -+ } else if (marker == JS_FRAME_MARK){ -+ CalleeSavedFrameSize = 2 * slotSize; /* frameType */ -+ } else { -+ assert("js-stub-call is illeagl ! "); -+ } -+ if (archType == Triple::aarch64) { -+ CalleeSavedFrameSize += slotSize; /* current SP */ -+ } -+ Offset += CalleeSavedFrameSize; ++ int64_t marker = 0x0; ++ MF.getFunction() ++ .getFnAttribute("js-stub-call") ++ .getValueAsString() ++ .getAsInteger(10, marker);//marker 1 break frame ++ if (marker == JS_ENTRY_FRAME_MARK) { ++ CalleeSavedFrameSize = 3 * slotSize; // 3 * slotSize;/* frameType + threadSP */ ++ } else if (marker == JS_FRAME_MARK){ ++ CalleeSavedFrameSize = 2 * slotSize; /* frameType */ ++ } else { ++ assert("js-stub-call is illeagl ! "); ++ } ++ if (archType == Triple::aarch64) { ++ CalleeSavedFrameSize += slotSize; /* current SP */ ++ } ++ Offset += CalleeSavedFrameSize; + } + } + #endif @@ -199,23 +200,159 @@ index 6da089d1859..271b4e157d9 100644 LowerPATCHABLE_FUNCTION_ENTER(*MI); return; diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp -index 651ad9ad4c8..6e4a674be51 100644 +index 651ad9ad4c8..540e8dab8fd 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp -@@ -872,6 +872,13 @@ static bool IsSVECalleeSave(MachineBasicBlock::iterator I) { +@@ -385,6 +385,7 @@ void AArch64FrameLowering::emitCalleeSavedFrameMoves( + unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true); + unsigned CFIIndex = MF.addFrameInst( + MCCFIInstruction::createOffset(nullptr, DwarfReg, Offset)); ++ + BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlags(MachineInstr::FrameSetup); +@@ -535,10 +536,11 @@ static MachineBasicBlock::iterator InsertSEH(MachineBasicBlock::iterator MBBI, + case AArch64::STPXpre: { + Register Reg0 = MBBI->getOperand(1).getReg(); + Register Reg1 = MBBI->getOperand(2).getReg(); +- if (Reg0 == AArch64::FP && Reg1 == AArch64::LR) ++ if (Reg0 == AArch64::FP && Reg1 == AArch64::LR) { + MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFPLR_X)) + .addImm(Imm * 8) + .setMIFlag(Flag); ++ } + else + MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveRegP_X)) + .addImm(RegInfo->getSEHRegNum(Reg0)) +@@ -584,10 +586,11 @@ static MachineBasicBlock::iterator InsertSEH(MachineBasicBlock::iterator MBBI, + case AArch64::LDPXi: { + Register Reg0 = MBBI->getOperand(0).getReg(); + Register Reg1 = MBBI->getOperand(1).getReg(); +- if (Reg0 == AArch64::FP && Reg1 == AArch64::LR) ++ if (Reg0 == AArch64::FP && Reg1 == AArch64::LR) { + MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFPLR)) + .addImm(Imm * 8) + .setMIFlag(Flag); ++ } + else + MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveRegP)) + .addImm(RegInfo->getSEHRegNum(Reg0)) +@@ -872,6 +875,13 @@ static bool IsSVECalleeSave(MachineBasicBlock::iterator I) { } } +#ifdef ARK_GC_SUPPORT +Triple::ArchType AArch64FrameLowering::GetArkSupportTarget() const +{ -+ return Triple::aarch64; ++ return Triple::aarch64; +} +#endif + void AArch64FrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.begin(); +@@ -980,6 +990,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, + unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet); + + auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject; ++ + // All of the remaining stack allocations are for locals. + AFI->setLocalStackSize(NumBytes - PrologueSaveSize); + bool CombineSPBump = shouldCombineCSRLocalStackBump(MF, NumBytes); +@@ -1020,11 +1031,42 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, + // mov fp,sp when FPOffset is zero. + // Note: All stores of callee-saved registers are marked as "FrameSetup". + // This code marks the instruction(s) that set the FP also. ++ + emitFrameOffset(MBB, MBBI, DL, AArch64::FP, AArch64::SP, + {FPOffset, MVT::i8}, TII, MachineInstr::FrameSetup, false, + NeedsWinCFI, &HasWinCFI); ++#ifdef ARK_GC_SUPPORT ++if (MF.getFunction().hasFnAttribute("js-stub-call")) { ++ int64_t marker = 0x0; ++ MF.getFunction() ++ .getFnAttribute("js-stub-call") ++ .getValueAsString() ++ .getAsInteger(10, marker);//marker 1 break frame ++ ++ /* x8-x15 volatile scratch registers, the callee isn't required to preserve the value ++ */ ++ BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVi64imm), AArch64::X15) ++ .addImm(marker) ++ .setMIFlags(MachineInstr::FrameSetup); ++ ++ BuildMI(MBB, MBBI, DL, TII->get(AArch64::STRXpre)) ++ .addReg(AArch64::FP, RegState::Define) ++ .addReg(AArch64::X15) ++ .addReg(AArch64::FP) ++ .addImm(-8); // 8: 1 slot size ++ ++ if (marker == JS_ENTRY_FRAME_MARK) { ++ BuildMI(MBB, MBBI, DL, TII->get(AArch64::STRXpre)) ++ .addReg(AArch64::FP, RegState::Define) ++ .addReg(AArch64::X15) ++ .addReg(AArch64::FP) ++ .addImm(-16); // 16: 2 slot size ++ } ++} ++#endif + } + ++ + if (windowsRequiresStackProbe(MF, NumBytes)) { + uint64_t NumWords = NumBytes >> 4; + if (NeedsWinCFI) { +@@ -1514,6 +1556,8 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF, + + const StackOffset &SVEStackSize = getSVEStackSize(MF); + ++ ++ + // If there is a single SP update, insert it before the ret and we're done. + if (CombineSPBump) { + assert(!SVEStackSize && "Cannot combine SP bump with SVE"); +@@ -1552,6 +1596,8 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF, + DeallocateAfter = SVEStackSize - DeallocateBefore; + } + ++ ++ + // Deallocate the SVE area. + if (SVEStackSize) { + if (AFI->isStackRealigned()) { +@@ -1632,6 +1678,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF, + // This must be placed after the callee-save restore code because that code + // assumes the SP is at the same location as it was after the callee-save save + // code in the prologue. ++ + if (AfterCSRPopSize) { + // Find an insertion point for the first ldp so that it goes before the + // shadow call stack epilog instruction. This ensures that the restore of +@@ -2079,6 +2126,7 @@ static void computeCalleeSaveRegisterPairs( + RegPairs.push_back(RPI); + if (RPI.isPaired()) + ++i; ++ + } + } + +@@ -2234,6 +2282,8 @@ bool AArch64FrameLowering::restoreCalleeSavedRegisters( + SmallVector RegPairs; + bool NeedsWinCFI = needsWinCFI(MF); + ++ ++ + if (MI != MBB.end()) + DL = MI->getDebugLoc(); + +@@ -2416,6 +2466,7 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, + CSStackSize += RegSize; + } + ++ + // Save number of saved regs, so we can easily update CSStackSize later. + unsigned NumSavedRegs = SavedRegs.count(); + diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h index b5719feb6b1..b09aa05176d 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h @@ -243,15 +380,16 @@ index b5719feb6b1..b09aa05176d 100644 bool canUseAsPrologue(const MachineBasicBlock &MBB) const override; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp -index 23f05eaad94..9d42a9d9af9 100644 +index 23f05eaad94..974d11aa701 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp -@@ -1498,6 +1498,9 @@ MachineBasicBlock *AArch64TargetLowering::EmitInstrWithCustomInserter( +@@ -1498,6 +1498,10 @@ MachineBasicBlock *AArch64TargetLowering::EmitInstrWithCustomInserter( case TargetOpcode::STACKMAP: case TargetOpcode::PATCHPOINT: +#ifdef ARK_GC_SUPPORT + case TargetOpcode::STATEPOINT: ++ MI.addOperand(*BB->getParent(), MachineOperand::CreateReg(AArch64::LR, true, true)); +#endif return emitPatchPoint(MI, BB); @@ -326,7 +464,7 @@ index 4724d6b8dae..2155ad923f9 100644 return AArch64TTIImpl::getIntImmCost(Imm, Ty); } diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp -index 6f26ca127f9..8db2d2c4b0b 100644 +index 6f26ca127f9..20b2a76518f 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -55,7 +55,11 @@ using namespace llvm; @@ -367,7 +505,7 @@ index 6f26ca127f9..8db2d2c4b0b 100644 } MCInst TmpInst; -@@ -2143,6 +2159,75 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { +@@ -2143,6 +2159,76 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, TmpInst); } @@ -433,6 +571,7 @@ index 6f26ca127f9..8db2d2c4b0b 100644 + EmitToStreamer(OutStreamer, + MCInstBuilder(CallOpcode).addOperand(CallTargetMCOp)); + } ++ + auto &Ctx = OutStreamer.getContext(); + MCSymbol *MILabel = Ctx.createTempSymbol(); + OutStreamer.EmitLabel(MILabel); @@ -519,311 +658,22 @@ index 66ad120a111..59335c77394 100644 // Remember that this is a user of a CP entry. unsigned CPI = I.getOperand(op).getIndex(); diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp -index cb98b2b34ef..b39bdf6f48e 100644 +index cb98b2b34ef..1806214932e 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp -@@ -353,6 +353,13 @@ static int getMaxFPOffset(const Function &F, const ARMFunctionInfo &AFI) { - return -AFI.getArgRegsSaveSize() - (8 * 4); - } - -+#ifdef ARK_GC_SUPPORT -+Triple::ArchType ARMFrameLowering::GetArkSupportTarget() const -+{ -+ return Triple::arm; -+} -+#endif -+ - void ARMFrameLowering::emitPrologue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - MachineBasicBlock::iterator MBBI = MBB.begin(); -@@ -967,6 +974,33 @@ ARMFrameLowering::ResolveFrameIndexReference(const MachineFunction &MF, - return Offset; - } - -+void ARMFrameLowering::emitPushJSInfo(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, -+ unsigned StrOpc, unsigned MIFlags) const -+{ -+ using RegAndKill = std::pair; -+ MachineFunction &MF = *MBB.getParent(); -+ const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); -+ bool isLiveIn = true; -+ DebugLoc DL; -+ SmallVector Regs; -+ Regs.push_back(std::make_pair(ARM::R11, /*isKill=*/!isLiveIn)); -+ BuildMI(MBB, MI, DL, TII.get(StrOpc), ARM::SP) -+ .addReg(Regs[0].first, getKillRegState(Regs[0].second)) -+ .addReg(ARM::SP) -+ .setMIFlags(MIFlags) -+ .addImm(-4) -+ .add(predOps(ARMCC::AL)); -+} -+#ifdef ARK_GC_SUPPORT -+void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, -+ MachineBasicBlock::iterator MI, -+ const std::vector &CSI, -+ unsigned StmOpc, unsigned StrOpc, -+ bool NoGap, -+ bool(*Func)(unsigned, bool), -+ unsigned NumAlignedDPRCS2Regs, -+ unsigned MIFlags, int multiCall) const { -+#else - void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, -@@ -975,6 +1009,7 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, - bool(*Func)(unsigned, bool), - unsigned NumAlignedDPRCS2Regs, - unsigned MIFlags) const { -+#endif - MachineFunction &MF = *MBB.getParent(); - const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); - const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); -@@ -1019,7 +1054,26 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, - llvm::sort(Regs, [&](const RegAndKill &LHS, const RegAndKill &RHS) { - return TRI.getEncodingValue(LHS.first) < TRI.getEncodingValue(RHS.first); - }); -+#ifdef ARK_GC_SUPPORT -+ SmallVector BeforeRegs = Regs; -+ if (multiCall != 0) { -+ Regs.clear(); -+ } -+ if (multiCall == 1) { -+ for (auto it: BeforeRegs) { -+ if (it.first == ARM::LR || it.first == ARM::R11) { -+ Regs.push_back(it); -+ } -+ } - -+ } else if (multiCall == 2) { -+ for (auto it: BeforeRegs) { -+ if ((it.first != ARM::LR) && (it.first != ARM::R11)) { -+ Regs.push_back(it); -+ } -+ } -+ } -+#endif - if (Regs.size() > 1 || StrOpc== 0) { - MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StmOpc), ARM::SP) - .addReg(ARM::SP) -@@ -1045,6 +1099,38 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, - } - } - -+void ARMFrameLowering::emitPopJSInfo(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, -+ unsigned LdrOpc) const -+{ -+ MachineFunction &MF = *MBB.getParent(); -+ const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); -+ SmallVector Regs; -+ unsigned Reg = ARM::R11; -+ Regs.push_back(Reg); -+ DebugLoc DL; -+ MachineInstrBuilder MIB = -+ BuildMI(MBB, MI, DL, TII.get(LdrOpc), Regs[0]) -+ .addReg(ARM::SP, RegState::Define) -+ .addReg(ARM::SP); -+ // ARM mode needs an extra reg0 here due to addrmode2. Will go away once -+ // that refactoring is complete (eventually). -+ if (LdrOpc == ARM::LDR_POST_REG || LdrOpc == ARM::LDR_POST_IMM) { -+ MIB.addReg(0); -+ MIB.addImm(ARM_AM::getAM2Opc(ARM_AM::add, 4, ARM_AM::no_shift)); -+ } else -+ MIB.addImm(4); -+ MIB.add(predOps(ARMCC::AL)); -+} -+ -+#ifdef ARK_GC_SUPPORT -+void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, -+ MachineBasicBlock::iterator MI, -+ std::vector &CSI, -+ unsigned LdmOpc, unsigned LdrOpc, -+ bool isVarArg, bool NoGap, -+ bool(*Func)(unsigned, bool), -+ unsigned NumAlignedDPRCS2Regs, int multiCall) const { -+#else - void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - std::vector &CSI, -@@ -1052,6 +1138,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, - bool isVarArg, bool NoGap, - bool(*Func)(unsigned, bool), - unsigned NumAlignedDPRCS2Regs) const { -+#endif - MachineFunction &MF = *MBB.getParent(); - const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); - const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); -@@ -1116,6 +1203,26 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, - return TRI.getEncodingValue(LHS) < TRI.getEncodingValue(RHS); - }); - -+#ifdef ARK_GC_SUPPORT -+ SmallVector BeforeRegs = Regs; -+ if (multiCall != 0) { -+ Regs.clear(); -+ } -+ if (multiCall == 1) { -+ for (auto it: BeforeRegs) { -+ if ((it != ARM::LR) && (it != ARM::R11)) { -+ Regs.push_back(it); -+ } -+ } -+ } else if (multiCall == 2) { -+ for (auto it: BeforeRegs) { -+ if ((it == ARM::LR) || (it == ARM::R11)) { -+ Regs.push_back(it); -+ } -+ } -+ } -+#endif -+ - if (Regs.size() > 1 || LdrOpc == 0) { - MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(LdmOpc), ARM::SP) - .addReg(ARM::SP) -@@ -1422,6 +1529,27 @@ static void emitAlignedDPRCS2Restores(MachineBasicBlock &MBB, - std::prev(MI)->addRegisterKilled(ARM::R4, TRI); - } - -+#ifdef ARK_GC_SUPPORT -+int ARMFrameLowering::GetSlotForJSInfo(const MachineFunction &MF) const { -+ int reserverSlot = 0; -+ if (MF.getFunction().hasFnAttribute("js-stub-call")) { -+ int64_t marker = 0x0; -+ MF.getFunction() -+ .getFnAttribute("js-stub-call") -+ .getValueAsString() -+ .getAsInteger(10, marker);//marker 1 break frame -+ if (marker == JS_ENTRY_FRAME_MARK) { -+ reserverSlot = 3; // 3 * slotSize;/* frameType + threadSP */ -+ } else if (marker == JS_FRAME_MARK){ -+ reserverSlot = 2; /* frameType */ -+ } else { -+ assert("js-stub-call is illeagl ! "); -+ } -+ } -+ return reserverSlot; -+} -+#endif -+ - bool ARMFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, -@@ -1436,9 +1564,23 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, - unsigned PushOneOpc = AFI->isThumbFunction() ? - ARM::t2STR_PRE : ARM::STR_PRE_IMM; - unsigned FltOpc = ARM::VSTMDDB_UPD; -+#ifdef ARK_GC_SUPPORT -+ DebugLoc DL; -+ const ARMBaseInstrInfo &TII = -+ *static_cast(MF.getSubtarget().getInstrInfo()); - unsigned NumAlignedDPRCS2Regs = AFI->getNumAlignedDPRCS2Regs(); -+ emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register, 0, -+ MachineInstr::FrameSetup, 1); -+ for (int i = 0; i < GetSlotForJSInfo(MF); i++) { -+ emitPushJSInfo(MBB, MI, PushOneOpc, MachineInstr::FrameSetup); -+ } -+ -+ emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register, 0, -+ MachineInstr::FrameSetup, 2); -+#else - emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register, 0, - MachineInstr::FrameSetup); -+#endif - emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea2Register, 0, - MachineInstr::FrameSetup); - emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register, -@@ -1477,8 +1619,20 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - NumAlignedDPRCS2Regs); - emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, - &isARMArea2Register, 0); -+#ifdef ARK_GC_SUPPORT -+ emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, -+ &isARMArea1Register, 0, 1); -+ -+ for (int i = 0; i < GetSlotForJSInfo(MF); i++) { -+ emitPopJSInfo(MBB, MI, LdrOpc); -+ } -+ -+ emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, -+ &isARMArea1Register, 0, 2); -+#else - emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, - &isARMArea1Register, 0); -+#endif - - return true; - } -@@ -1573,7 +1727,7 @@ static unsigned estimateRSStackSizeLimit(MachineFunction &MF, +@@ -1573,6 +1573,7 @@ static unsigned estimateRSStackSizeLimit(MachineFunction &MF, Limit = std::min(Limit, ((1U << 7) - 1) * 4); break; default: -- llvm_unreachable("Unhandled addressing mode in stack size limit calculation"); + break; + llvm_unreachable("Unhandled addressing mode in stack size limit calculation"); } break; // At most one FI per instruction - } -diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h -index 0462b01af70..c410326f432 100644 ---- a/llvm/lib/Target/ARM/ARMFrameLowering.h -+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h -@@ -13,6 +13,9 @@ - #include "llvm/CodeGen/TargetFrameLowering.h" - #include - -+#define JS_ENTRY_FRAME_MARK 1 -+#define JS_FRAME_MARK 0 -+ - namespace llvm { - - class ARMSubtarget; -@@ -30,6 +33,9 @@ public: - /// the function. - void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; - void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; -+#ifdef ARK_GC_SUPPORT -+ Triple::ArchType GetArkSupportTarget() const override; -+#endif - - bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, -@@ -72,6 +78,24 @@ public: - } - - private: -+ -+#ifdef ARK_GC_SUPPORT -+ void emitPushInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, -+ const std::vector &CSI, unsigned StmOpc, -+ unsigned StrOpc, bool NoGap, -+ bool(*Func)(unsigned, bool), unsigned NumAlignedDPRCS2Regs, -+ unsigned MIFlags = 0, int multiCall = 0) const; -+ void emitPushJSInfo(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, -+ unsigned StrOpc, unsigned MIFlags) const; -+ void emitPopInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, -+ std::vector &CSI, unsigned LdmOpc, -+ unsigned LdrOpc, bool isVarArg, bool NoGap, -+ bool(*Func)(unsigned, bool), -+ unsigned NumAlignedDPRCS2Regs, int multiCall = 0) const; -+ void emitPopJSInfo(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, -+ unsigned LdrOpc) const; -+ int GetSlotForJSInfo(const MachineFunction &MF) const; -+#else - void emitPushInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector &CSI, unsigned StmOpc, - unsigned StrOpc, bool NoGap, -@@ -82,7 +106,7 @@ private: - unsigned LdrOpc, bool isVarArg, bool NoGap, - bool(*Func)(unsigned, bool), - unsigned NumAlignedDPRCS2Regs) const; -- -+#endif - MachineBasicBlock::iterator - eliminateCallFramePseudoInstr(MachineFunction &MF, - MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp -index 9f504b1eaa4..cf2f5f50b14 100644 +index 9f504b1eaa4..30a1baf5c85 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp -@@ -10551,6 +10551,13 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, +@@ -10551,6 +10551,14 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, llvm_unreachable("Unexpected instr type to insert"); } @@ -831,6 +681,7 @@ index 9f504b1eaa4..cf2f5f50b14 100644 + case TargetOpcode::STATEPOINT: + case TargetOpcode::STACKMAP: + case TargetOpcode::PATCHPOINT: ++ MI.addOperand(*BB->getParent(), MachineOperand::CreateReg(ARM::LR, true, true)); + return emitPatchPoint(MI, BB); +#endif + @@ -838,7 +689,7 @@ index 9f504b1eaa4..cf2f5f50b14 100644 case ARM::tLDR_postidx: { MachineOperand Def(MI.getOperand(1)); diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp -index 1da20371caf..a73d3cd8053 100644 +index 1da20371caf..e0264827556 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -1168,6 +1168,25 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, @@ -907,20 +758,20 @@ index 1da20371caf..a73d3cd8053 100644 + .getValueAsString() + .getAsInteger(10, marker);//marker 1 break frame + if (marker == JS_ENTRY_FRAME_MARK) { -+ SpillSlotOffset -= 3 * SlotSize; // add type and thread.fp -+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); -+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); -+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); -+ CalleeSavedFrameSize += (2 * SlotSize); ++ SpillSlotOffset -= 3 * SlotSize; // add type and thread.fp ++ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); ++ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); ++ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); ++ CalleeSavedFrameSize += (2 * SlotSize); + } else { -+ SpillSlotOffset -= 2 * SlotSize; // add type -+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); -+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); -+ CalleeSavedFrameSize += SlotSize; ++ SpillSlotOffset -= 2 * SlotSize; // add type ++ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); ++ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); ++ CalleeSavedFrameSize += SlotSize; + } + } else { -+ SpillSlotOffset -= SlotSize; // add type and thread.fp -+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); ++ SpillSlotOffset -= SlotSize; // add type and thread.fp ++ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset); + } +#else SpillSlotOffset -= SlotSize; diff --git a/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp b/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp index b553c49e9e..e901208246 100644 --- a/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp +++ b/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp @@ -23,6 +23,8 @@ #include "ecmascript/mem/object_xray.h" #include "ecmascript/mem/slots.h" +using namespace panda::ecmascript; + namespace kungfu { std::string LocationTy::TypeToString(Kind loc) const { @@ -42,21 +44,168 @@ std::string LocationTy::TypeToString(Kind loc) const } } -const DwarfRegAndOffsetTypeVector* LLVMStackMapParser::StackMapByAddr(uintptr_t callSiteAddr) const +const CallSiteInfo* LLVMStackMapParser::GetCallSiteInfoByPc(uintptr_t callSiteAddr) const +{ + auto it = pc2CallSiteInfo_.find(callSiteAddr); + if (it != pc2CallSiteInfo_.end()) { + return &(it->second); + } + return nullptr; +} + +const CallSiteInfo* LLVMStackMapParser::GetCallSiteInfoByPatchID(uint64_t patchPointId) const { - auto it = callSiteInfos_.find(callSiteAddr); - if (it != callSiteInfos_.end()) { + auto it = pid2CallSiteInfo_.find(patchPointId); + if (it != pid2CallSiteInfo_.end()) { return &(it->second); } return nullptr; } -bool LLVMStackMapParser::StackMapByFuncAddrFp(uintptr_t callSiteAddr, uintptr_t frameFp, +void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, + panda::ecmascript::OptLeaveFrame *state) +{ + int i = 0; + uintptr_t address = 0; + uintptr_t base = 0; + uintptr_t derived = 0; + for (auto &info: *infos) { + if (info.first == panda::ecmascript::FrameCommonConstants::SP_DWARF_REG_NUM) { + uintptr_t rsp = state->sp; + address = rsp + info.second; + LOG_ECMA(DEBUG) << std::dec << "SP_DWARF_REG_NUM: info.second:" << info.second + << std::hex << "rsp :" << rsp; + } else if (info.first == panda::ecmascript::FrameCommonConstants::FP_DWARF_REG_NUM) { + uintptr_t fp = state->fp; + address = fp + info.second; + LOG_ECMA(DEBUG) << std::dec << "FP_DWARF_REG_NUM: info.second:" << info.second + << std::hex << "rfp :" << fp; + } else { + LOG_ECMA(DEBUG) << "REG_NUM : info.first:" << info.first; + abort(); + } + + if (IsDeriveredPointer(i)) { + derived = reinterpret_cast(address); + if (base == derived) { + LOG_ECMA(INFO) << std::hex << "visit base:" << base << " base Value: " << + *reinterpret_cast(base); + } else { + LOG_ECMA(INFO) << std::hex << "push base:" << base << " base Value: " << + *reinterpret_cast(base) << " derived:" << derived; + } + } else { + base = reinterpret_cast(address); + } + i++; + } + i = 0; +} + +bool LLVMStackMapParser::GetStackMapIterm(panda::ecmascript::OptLeaveFrame *state, + const RootVisitor &v0, const RootRangeVisitor &v1, + panda::ecmascript::ChunkMap *data, + [[maybe_unused]] bool isVerifying) const +{ + ASSERT(state); + uint64_t patchpointId = state->patchId; + const CallSiteInfo *infos = GetCallSiteInfoByPc(patchpointId); + if (infos == nullptr) { + return false; + } + uintptr_t address = 0; + uintptr_t base = 0; + uintptr_t derived = 0; + int i = 0; +#if ECMASCRIPT_ENABLE_COMPILER_LOG + PrintCallSiteInfo(infos, state); +#endif + + for (auto &info: *infos) { + if (info.first == panda::ecmascript::FrameCommonConstants::SP_DWARF_REG_NUM) { + uintptr_t rsp = state->sp; + address = rsp + info.second; + } else if (info.first == panda::ecmascript::FrameCommonConstants::FP_DWARF_REG_NUM) { + uintptr_t fp = state->fp; + address = fp + info.second; + } else { + abort(); + } + if (IsDeriveredPointer(i)) { + derived = reinterpret_cast(address); + if (base == derived) { + v0(panda::ecmascript::Root::ROOT_FRAME, panda::ecmascript::ObjectSlot(base)); + } else { +#if ECMASCRIPT_ENABLE_HEAP_VERIFY + if (!isVerifying) { +#endif + data->emplace(std::make_pair(base, derived), *reinterpret_cast(base)); +#if ECMASCRIPT_ENABLE_HEAP_VERIFY + } +#endif + } + } else { + base = reinterpret_cast(address); + } + i++; + } + return true; +} + +void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, + uintptr_t *fp) +{ + int i = 0; + uintptr_t address = 0; + uintptr_t base = 0; + uintptr_t derived = 0; + for (auto &info: *infos) { + if (info.first == panda::ecmascript::FrameCommonConstants::SP_DWARF_REG_NUM) { +#ifdef PANDA_TARGET_ARM64 + uintptr_t *curFp = reinterpret_cast(*fp); + uintptr_t *rsp = reinterpret_cast(*(curFp + panda::ecmascript::FrameCommonConstants::SP_OFFSET)); +#else + uintptr_t *rsp = fp + panda::ecmascript::FrameCommonConstants::SP_OFFSET; +#endif + address = reinterpret_cast(rsp) + info.second; + LOG_ECMA(DEBUG) << "SP_DWARF_REG_NUM: info.second:" << info.second << " rbp offset:" << + reinterpret_cast(*fp) - address << "rsp :" << rsp; + } else if (info.first == panda::ecmascript::FrameCommonConstants::FP_DWARF_REG_NUM) { + uintptr_t tmpFp = *fp; + address = tmpFp + info.second; + LOG_ECMA(DEBUG) << "FP_DWARF_REG_NUM: info.second:" << info.second; + } else { + LOG_ECMA(DEBUG) << "REG_NUM : info.first:" << info.first; + abort(); + } + + if (IsDeriveredPointer(i)) { + derived = reinterpret_cast(address); + if (base == derived) { + LOG_ECMA(DEBUG) << std::hex << "visit base:" << base << " base Value: " << + *reinterpret_cast(base); + } else { + LOG_ECMA(DEBUG) << std::hex << "push base:" << base << " base Value: " << + *reinterpret_cast(base) << " derived:" << derived; + } + } else { + base = reinterpret_cast(address); + } + i++; + } +} + +bool LLVMStackMapParser::IsDeriveredPointer(int callsitetime) const +{ + return callsitetime & 1; +} + +bool LLVMStackMapParser::GetStackMapIterm(uintptr_t callSiteAddr, uintptr_t frameFp, const RootVisitor &v0, const RootRangeVisitor &v1, - panda::ecmascript::ChunkVector *data, + panda::ecmascript::ChunkMap *data, [[maybe_unused]] bool isVerifying) const { - const DwarfRegAndOffsetTypeVector *infos = StackMapByAddr(callSiteAddr); + const CallSiteInfo *infos = GetCallSiteInfoByPc(callSiteAddr); if (infos == nullptr) { return false; } @@ -65,49 +214,34 @@ bool LLVMStackMapParser::StackMapByFuncAddrFp(uintptr_t callSiteAddr, uintptr_t uintptr_t base = 0; uintptr_t derived = 0; int i = 0; +#if ECMASCRIPT_ENABLE_COMPILER_LOG + PrintCallSiteInfo(infos, fp); +#endif for (auto &info: *infos) { - if (info.first == panda::ecmascript::FrameConst::SP_DWARF_REG_NUM) { + if (info.first == panda::ecmascript::FrameCommonConstants::SP_DWARF_REG_NUM) { #ifdef PANDA_TARGET_ARM64 uintptr_t *curFp = reinterpret_cast(*fp); - uintptr_t *rsp = reinterpret_cast(*(curFp + panda::ecmascript::FrameConst::SP_OFFSET)); + uintptr_t *rsp = reinterpret_cast(*(curFp + panda::ecmascript::FrameCommonConstants::SP_OFFSET)); #else - uintptr_t *rsp = fp + panda::ecmascript::FrameConst::SP_OFFSET; + uintptr_t *rsp = fp + panda::ecmascript::FrameCommonConstants::SP_OFFSET; #endif address = reinterpret_cast(rsp) + info.second; -#if ECMASCRIPT_ENABLE_COMPILER_LOG - LOG_ECMA(DEBUG) << "SP_DWARF_REG_NUM: info.second:" << info.second << " rbp offset:" << - reinterpret_cast(*fp) - address << "rsp :" << rsp; -#endif - } else if (info.first == panda::ecmascript::FrameConst::FP_DWARF_REG_NUM) { + } else if (info.first == panda::ecmascript::FrameCommonConstants::FP_DWARF_REG_NUM) { uintptr_t tmpFp = *fp; address = tmpFp + info.second; -#if ECMASCRIPT_ENABLE_COMPILER_LOG - LOG_ECMA(DEBUG) << "FP_DWARF_REG_NUM: info.second:" << info.second; -#endif } else { -#if ECMASCRIPT_ENABLE_COMPILER_LOG - LOG_ECMA(DEBUG) << "REG_NUM : info.first:" << info.first; -#endif abort(); } - if (i & 0x1) { + if (IsDeriveredPointer(i)) { derived = reinterpret_cast(address); if (base == derived) { -#if ECMASCRIPT_ENABLE_COMPILER_LOG - LOG_ECMA(DEBUG) << std::hex << "visit base:" << base << " base Value: " << - *reinterpret_cast(base); -#endif v0(panda::ecmascript::Root::ROOT_FRAME, panda::ecmascript::ObjectSlot(base)); } else { -#if ECMASCRIPT_ENABLE_COMPILER_LOG - LOG_ECMA(DEBUG) << std::hex << "push base:" << base << " base Value: " << - *reinterpret_cast(base) << " derived:" << derived; -#endif #if ECMASCRIPT_ENABLE_HEAP_VERIFY if (!isVerifying) { #endif - data->emplace_back(std::make_tuple(base, *reinterpret_cast(base), derived)); + data->emplace(std::make_pair(base, derived), *reinterpret_cast(base)); #if ECMASCRIPT_ENABLE_HEAP_VERIFY } #endif @@ -129,19 +263,29 @@ void LLVMStackMapParser::CalcCallSite() struct LocationTy loc = llvmStackMap_.StkMapRecord[recordNum + recordId].Locations[j]; uint32_t instructionOffset = recordHead.InstructionOffset; uintptr_t callsite = address + instructionOffset; + uint64_t patchPointID = recordHead.PatchPointID; if (loc.location == LocationTy::Kind::INDIRECT) { #if ECMASCRIPT_ENABLE_COMPILER_LOG LOG_ECMA(DEBUG) << "DwarfRegNum:" << loc.DwarfRegNum << " loc.OffsetOrSmallConstant:" << loc.OffsetOrSmallConstant << "address:" << address << " instructionOffset:" << - instructionOffset << " callsite:" << callsite; + instructionOffset << " callsite:" << " patchPointID :" << std::hex << patchPointID << callsite; #endif DwarfRegAndOffsetType info(loc.DwarfRegNum, loc.OffsetOrSmallConstant); - auto it = callSiteInfos_.find(callsite); - if (callSiteInfos_.find(callsite) == callSiteInfos_.end()) { - callSiteInfos_.insert(std::pair(callsite, {info})); + auto it = pc2CallSiteInfo_.find(callsite); + if (pc2CallSiteInfo_.find(callsite) == pc2CallSiteInfo_.end()) { + pc2CallSiteInfo_.insert(std::pair(callsite, {info})); } else { it->second.emplace_back(info); } + + auto it2 = pid2CallSiteInfo_.find(patchPointID); + if (pid2CallSiteInfo_.find(patchPointID) == pid2CallSiteInfo_.end()) { + pid2CallSiteInfo_.insert(std::pair(patchPointID, + {info})); + } else { + it2->second.emplace_back(info); + } + } } }; @@ -172,6 +316,7 @@ bool LLVMStackMapParser::CalculateStackMap(std::unique_ptr stackMapA auto stkRecord = dataInfo_->Read(); llvmStackMap_.StkSizeRecords.push_back(stkRecord); } + for (uint32_t i = 0; i < numConstants; i++) { auto val = dataInfo_->Read(); llvmStackMap_.Constants.push_back(val); @@ -223,7 +368,8 @@ bool LLVMStackMapParser::CalculateStackMap(std::unique_ptr stackMapA LOG_ECMA(DEBUG) << std::dec << i << "th function " << std::hex << hostAddr << " ---> " << deviceAddr; #endif } - callSiteInfos_.clear(); + pc2CallSiteInfo_.clear(); + pid2CallSiteInfo_.clear(); CalcCallSite(); return true; } diff --git a/ecmascript/compiler/llvm/llvm_stackmap_parser.h b/ecmascript/compiler/llvm/llvm_stackmap_parser.h index 99dfacca2b..23f0539457 100644 --- a/ecmascript/compiler/llvm/llvm_stackmap_parser.h +++ b/ecmascript/compiler/llvm/llvm_stackmap_parser.h @@ -23,15 +23,15 @@ #include #include "ecmascript/common.h" #include "ecmascript/ecma_macros.h" - +#include "ecmascript/interpreter/interpreter-inl.h" namespace kungfu { using OffsetType = int32_t; using DwarfRegType = uint16_t; using DwarfRegAndOffsetType = std::pair; -using DwarfRegAndOffsetTypeVector = std::vector; +using CallSiteInfo = std::vector; using Fun2InfoType = std::pair; -using DerivedData = panda::ecmascript::DerivedData; +using DerivedDataKey = panda::ecmascript::DerivedDataKey; using RootVisitor = panda::ecmascript::RootVisitor; using RootRangeVisitor = panda::ecmascript::RootRangeVisitor; @@ -201,15 +201,21 @@ public: { llvmStackMap_.Print(); } - const DwarfRegAndOffsetTypeVector *StackMapByAddr(uintptr_t funcAddr) const; - bool StackMapByFuncAddrFp(uintptr_t callSiteAddr, uintptr_t frameFp, const RootVisitor &v0, - const RootRangeVisitor &v1, panda::ecmascript::ChunkVector *data, + const CallSiteInfo *GetCallSiteInfoByPc(uintptr_t funcAddr) const; + bool GetStackMapIterm(uintptr_t callSiteAddr, uintptr_t frameFp, const RootVisitor &v0, + const RootRangeVisitor &v1, panda::ecmascript::ChunkMap *data, [[maybe_unused]] bool isVerifying) const; + bool GetStackMapIterm(panda::ecmascript::OptLeaveFrame *state, + const RootVisitor &v0, const RootRangeVisitor &v1, + panda::ecmascript::ChunkMap *data, + [[maybe_unused]] bool isVerifying) const; + private: LLVMStackMapParser() { stackMapAddr_ = nullptr; - callSiteInfos_.clear(); + pc2CallSiteInfo_.clear(); + pid2CallSiteInfo_.clear(); dataInfo_ = nullptr; } ~LLVMStackMapParser() @@ -217,13 +223,19 @@ private: if (stackMapAddr_) { stackMapAddr_.release(); } - callSiteInfos_.clear(); + pc2CallSiteInfo_.clear(); + pid2CallSiteInfo_.clear(); dataInfo_ = nullptr; } void CalcCallSite(); + bool IsDeriveredPointer(int callsitetime) const; + const CallSiteInfo* GetCallSiteInfoByPatchID(uint64_t patchPointId) const; + void PrintCallSiteInfo(const CallSiteInfo *infos, panda::ecmascript::OptLeaveFrame *state); + void PrintCallSiteInfo(const CallSiteInfo *infos, uintptr_t *fp); std::unique_ptr stackMapAddr_; struct LLVMStackMap llvmStackMap_; - std::unordered_map callSiteInfos_; + std::unordered_map pc2CallSiteInfo_; + std::unordered_map pid2CallSiteInfo_; [[maybe_unused]] std::unique_ptr dataInfo_; }; } // namespace kungfu diff --git a/ecmascript/compiler/llvm_codegen.cpp b/ecmascript/compiler/llvm_codegen.cpp index 8c9ebe7aa5..3a877a913c 100644 --- a/ecmascript/compiler/llvm_codegen.cpp +++ b/ecmascript/compiler/llvm_codegen.cpp @@ -145,7 +145,54 @@ bool LLVMAssembler::BuildMCJITEngine() return true; } -void LLVMAssembler::BuildAndRunPasses() const +void LLVMAssembler::RewritePatchPointIdOfStatePoint(LLVMValueRef instruction, uint64_t &callInsNum, uint64_t &funcNum) +{ + if (LLVMIsACallInst(instruction) && !LLVMIsAIntrinsicInst(instruction)) { + const char attrName[] = "statepoint-id"; + uint64_t id = (funcNum << 16) | callInsNum; + std::string patchId = std::to_string(id); + LLVMAttributeRef attr = LLVMCreateStringAttribute(LLVMGetGlobalContext(), + attrName, sizeof(attrName) - 1, patchId.c_str(), patchId.size()); + LLVMAddCallSiteAttribute(instruction, LLVMAttributeFunctionIndex, attr); + callInsNum++; + LLVMValueRef targetStoreInst = LLVMGetPreviousInstruction(LLVMGetPreviousInstruction( + LLVMGetPreviousInstruction(instruction))); + if (LLVMGetInstructionOpcode(targetStoreInst) == LLVMStore) { + LLVMSetOperand(targetStoreInst, 0, LLVMConstInt(LLVMInt64Type(), id, 0)); + } + } +} + +void LLVMAssembler::FillPatchPointIDs() +{ + LLVMValueRef func; + uint64_t funcNum = 0; + func = LLVMGetFirstFunction(module_); + while (func) { + if (LLVMIsDeclaration(func)) { + func = LLVMGetNextFunction(func); + funcNum++; + continue; + } + LLVMBasicBlockRef bb; + LLVMValueRef instruction; + unsigned instructionNum = 0; + unsigned bbNum = 0; + uint64_t callInsNum = 0; + for (bb = LLVMGetFirstBasicBlock(func); bb; bb = LLVMGetNextBasicBlock(bb)) { + bbNum++; + for (instruction = LLVMGetFirstInstruction(bb); instruction; + instruction = LLVMGetNextInstruction(instruction)) { + instructionNum++; + RewritePatchPointIdOfStatePoint(instruction, callInsNum, funcNum); + } + } + func = LLVMGetNextFunction(func); + funcNum++; + } +} + +void LLVMAssembler::BuildAndRunPasses() { COMPILER_LOG(DEBUG) << "BuildAndRunPasses - "; LLVMPassManagerBuilderRef pmBuilder = LLVMPassManagerBuilderCreate(); @@ -161,6 +208,7 @@ void LLVMAssembler::BuildAndRunPasses() const for (LLVMValueRef fn = LLVMGetFirstFunction(module_); fn; fn = LLVMGetNextFunction(fn)) { LLVMRunFunctionPassManager(funcPass, fn); } + FillPatchPointIDs(); LLVMFinalizeFunctionPassManager(funcPass); LLVMRunPassManager(modPass, module_); LLVMDisposePassManager(funcPass); diff --git a/ecmascript/compiler/llvm_codegen.h b/ecmascript/compiler/llvm_codegen.h index 78e7ff1d79..1be1d5358b 100644 --- a/ecmascript/compiler/llvm_codegen.h +++ b/ecmascript/compiler/llvm_codegen.h @@ -180,8 +180,10 @@ public: private: void UseRoundTripSectionMemoryManager(); bool BuildMCJITEngine(); - void BuildAndRunPasses() const; + void BuildAndRunPasses(); void BuildSimpleFunction(); + void FillPatchPointIDs(); + void RewritePatchPointIdOfStatePoint(LLVMValueRef instruction, uint64_t &callInsNum, uint64_t &funcNum); void Initialize(); void InitMember(); diff --git a/ecmascript/compiler/llvm_ir_builder.cpp b/ecmascript/compiler/llvm_ir_builder.cpp index b479bf1ff1..1f231769d9 100644 --- a/ecmascript/compiler/llvm_ir_builder.cpp +++ b/ecmascript/compiler/llvm_ir_builder.cpp @@ -43,6 +43,37 @@ LLVMIRBuilder::LLVMIRBuilder(const std::vector> *schedule, context_ = LLVMGetGlobalContext(); LLVMSetGC(function_, "statepoint-example"); bbIdMapBb_.clear(); + if (compCfg_->IsArm32()) { + LLVMTypeRef elementTypes[] = { + LLVMInt64Type(), // frameType + LLVMPointerType(LLVMInt64Type(), 0), // prev + LLVMInt32Type(), // sp + LLVMInt32Type(), // fp + LLVMInt64Type(), // patchpointId + }; + slotSize_ = panda::ecmascript::FrameCommonConstants::ARM32_SLOT_SIZE; + slotType_ = LLVMInt32Type(); + optFrameType_ = LLVMStructType(elementTypes, sizeof(elementTypes) / sizeof(LLVMTypeRef), 0); + } else { + LLVMTypeRef elementTypes[] = { + LLVMInt64Type(), // frameType + LLVMPointerType(LLVMInt64Type(), 0), // prev + LLVMInt64Type(), // sp + LLVMInt64Type(), // fp + LLVMInt64Type(), // patchpointId + }; + slotSize_ = panda::ecmascript::FrameCommonConstants::AARCH64_SLOT_SIZE; + slotType_ = LLVMInt64Type(); + optFrameType_ = LLVMStructType(elementTypes, sizeof(elementTypes) / sizeof(LLVMTypeRef), 0); + } + optFrameSize_ = compCfg_->GetGlueOffset(JSThread::GlueID::OPT_LEAVE_FRAME_SIZE); + interpretedFrameSize_ = compCfg_->GetGlueOffset(JSThread::GlueID::FRAME_STATE_SIZE); + if (compCfg_->IsArm32()) { + // hard float instruction + LLVMAddTargetDependentFunctionAttr(function_, "target-features", + "+armv7-a"); + } + optLeaveFramePrevOffset_ = compCfg_->GetGlueOffset(JSThread::GlueID::OPT_LEAVE_FRAME_PREV_OFFSET); } LLVMIRBuilder::~LLVMIRBuilder() @@ -152,7 +183,7 @@ void LLVMIRBuilder::AssignHandleMap() {OpCode::INT32_SMOD, &LLVMIRBuilder::HandleIntMod}, {OpCode::TAGGED_POINTER_CALL, &LLVMIRBuilder::HandleCall}, }; - opCodeHandleIgnore= { + opCodeHandleIgnore = { OpCode::NOP, OpCode::CIRCUIT_ROOT, OpCode::DEPEND_ENTRY, OpCode::FRAMESTATE_ENTRY, OpCode::RETURN_LIST, OpCode::THROW_LIST, OpCode::CONSTANT_LIST, OpCode::ARG_LIST, OpCode::THROW, @@ -294,39 +325,25 @@ void LLVMIRBuilder::PrologueHandle(LLVMModuleRef &module, LLVMBuilderRef &builde -8 type -16 pre frame thread fp for 32 arm bit system: - 0 pre fp <-- fp - -4 type - -8 pre frame thread fp + not support for arm64 system 0 pre fp/ other regs <-- fp -8 type -16 pre frame thread fp -24 current sp before call other function */ + if (compCfg_->IsArm32() || compCfg_->IsAArch64() || compCfg_->IsAmd64()) { + return; + } auto frameType = circuit_->GetFrameType(); LLVMAddTargetDependentFunctionAttr(function_, "frame-pointer", "all"); - if (compCfg_->IsArm32()) { - LLVMAddTargetDependentFunctionAttr(function_, "target-features", "+vfp2"); - } LLVMValueRef llvmFpAddr = CallingFp(module_, builder_, false); - int slotSize = 0; - LLVMTypeRef llvmSlotType = nullptr; - if (compCfg_->IsAmd64() || compCfg_->IsAArch64()) { - slotSize = panda::ecmascript::FrameConst::AARCH64_SLOT_SIZE; // 64bit slot size - llvmSlotType = LLVMInt64Type(); - } else if (compCfg_->IsArm32()) { - slotSize = panda::ecmascript::FrameConst::ARM32_SLOT_SIZE; // 32bit slot size - llvmSlotType = LLVMInt32Type(); - return; - } else { - ASSERT_PRINT(llvmSlotType == nullptr, " triple is not supported !"); - } - LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder, llvmFpAddr, llvmSlotType, "cast_int_t"); - LLVMValueRef frameTypeSlotAddr = LLVMBuildSub(builder, frameAddr, LLVMConstInt(llvmSlotType, - slotSize, false), ""); + LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder, llvmFpAddr, slotType_, "cast_int_t"); + LLVMValueRef frameTypeSlotAddr = LLVMBuildSub(builder, frameAddr, LLVMConstInt(slotType_, + slotSize_, false), ""); LLVMValueRef addr = LLVMBuildIntToPtr(builder, frameTypeSlotAddr, - LLVMPointerType(llvmSlotType, 0), "frameType.Addr"); + LLVMPointerType(slotType_, 0), "frameType.Addr"); if (frameType == panda::ecmascript::FrameType::OPTIMIZED_FRAME) { LLVMAddTargetDependentFunctionAttr(function_, "js-stub-call", "0"); @@ -337,7 +354,7 @@ void LLVMIRBuilder::PrologueHandle(LLVMModuleRef &module, LLVMBuilderRef &builde ASSERT_PRINT(static_cast(frameType), "is not support !"); } - LLVMValueRef llvmFrameType = LLVMConstInt(llvmSlotType, static_cast(frameType), 0); + LLVMValueRef llvmFrameType = LLVMConstInt(slotType_, static_cast(frameType), 0); (void)llvmFrameType; LLVMValueRef value = LLVMBuildStore(builder_, llvmFrameType, addr); @@ -349,12 +366,12 @@ void LLVMIRBuilder::PrologueHandle(LLVMModuleRef &module, LLVMBuilderRef &builde LLVMTypeRef glue_type = LLVMTypeOf(glue); LLVMValueRef rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::CURRENT_FRAME), 0); LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, ""); - LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, rtbaseoffset, LLVMPointerType(llvmSlotType, 0), ""); + LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, rtbaseoffset, LLVMPointerType(slotType_, 0), ""); LLVMValueRef threadFpValue = LLVMBuildLoad(builder_, rtbaseAddr, ""); static constexpr int g_LLVMFrameOffset = 2; - addr = LLVMBuildSub(builder, frameAddr, LLVMConstInt(llvmSlotType, g_LLVMFrameOffset * slotSize, false), ""); + addr = LLVMBuildSub(builder, frameAddr, LLVMConstInt(slotType_, g_LLVMFrameOffset * slotSize_, false), ""); value = LLVMBuildStore(builder_, threadFpValue, - LLVMBuildIntToPtr(builder_, addr, LLVMPointerType(llvmSlotType, 0), "cast")); + LLVMBuildIntToPtr(builder_, addr, LLVMPointerType(slotType_, 0), "cast")); LOG_ECMA(DEBUG) << "store value:" << value << " " << "value type" << LLVMTypeOf(value); } @@ -376,7 +393,7 @@ LLVMValueRef LLVMIRBuilder::CallingFp(LLVMModuleRef &module, LLVMBuilderRef &bui return fAddrRet; } -LLVMValueRef LLVMIRBuilder::CallerSp(LLVMModuleRef &module, LLVMBuilderRef &builder, +LLVMValueRef LLVMIRBuilder::ReadRegister(LLVMModuleRef &module, LLVMBuilderRef &builder, LLVMMetadataRef meta) { std::vector args = {LLVMMetadataAsValue(context_, meta)}; @@ -389,7 +406,6 @@ LLVMValueRef LLVMIRBuilder::CallerSp(LLVMModuleRef &module, LLVMBuilderRef &buil auto fnTy = LLVMFunctionType(LLVMInt64Type(), paramTys1, 1, 0); fn = LLVMAddFunction(module, "llvm.read_register.i64", fnTy); } - LLVMDumpValue(fn); LLVMValueRef fAddrRet = LLVMBuildCall(builder_, fn, args.data(), 1, ""); return fAddrRet; } @@ -468,24 +484,133 @@ void LLVMIRBuilder::HandleCall(GateRef gate) } } -void LLVMIRBuilder::SaveCallerSp() +LLVMValueRef LLVMIRBuilder::GetCurrentSP() +{ + LLVMMetadataRef meta; + if (compCfg_->IsAmd64()) { + meta = LLVMMDStringInContext2(context_, "rsp", 4); // 4 : 4 means len of "rsp" + } else { + meta = LLVMMDStringInContext2(context_, "sp", 3); // 3 : 3 means len of "sp" + } + LLVMMetadataRef metadataNode = LLVMMDNodeInContext2(context_, &meta, 1); + LLVMValueRef spValue = ReadRegister(module_, builder_, metadataNode); + return spValue; +} + +void LLVMIRBuilder::SaveCurrentSP() { if (compCfg_->IsAArch64()) { - int slotSize = 8; - LLVMTypeRef llvmSlotType = LLVMInt64Type(); LLVMValueRef llvmFpAddr = CallingFp(module_, builder_, false); - LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder_, llvmFpAddr, llvmSlotType, "cast_int_t"); - LLVMValueRef frameSpSlotAddr = LLVMBuildSub(builder_, frameAddr, LLVMConstInt(llvmSlotType, - 3 * slotSize, false), ""); // 3: type + threadsp + current sp + LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder_, llvmFpAddr, slotType_, "cast_int_t"); + LLVMValueRef frameSpSlotAddr = LLVMBuildSub(builder_, frameAddr, LLVMConstInt(slotType_, + 3 * slotSize_, false), ""); // 3: type + threadsp + current sp LLVMValueRef addr = LLVMBuildIntToPtr(builder_, frameSpSlotAddr, - LLVMPointerType(llvmSlotType, 0), "frameType.Addr"); + LLVMPointerType(slotType_, 0), "frameType.Addr"); LLVMMetadataRef meta = LLVMMDStringInContext2(context_, "sp", 3); // 3 : 3 means len of "sp" LLVMMetadataRef metadataNode = LLVMMDNodeInContext2(context_, &meta, 1); - LLVMValueRef spValue = CallerSp(module_, builder_, metadataNode); + LLVMValueRef spValue = ReadRegister(module_, builder_, metadataNode); LLVMBuildStore(builder_, spValue, addr); } } +LLVMValueRef LLVMIRBuilder::GetCurrentSPFrameAddr() +{ + LLVMValueRef glue = LLVMGetParam(function_, 0); + LLVMTypeRef glue_type = LLVMTypeOf(glue); + LLVMValueRef rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::CURRENT_FRAME), 0); + LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, ""); + return rtbaseoffset; +} + +LLVMValueRef LLVMIRBuilder::GetCurrentSPFrame() +{ + LLVMValueRef addr = GetCurrentSPFrameAddr(); + LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, addr, LLVMPointerType(slotType_, 0), ""); + LLVMValueRef currentSpFrame = LLVMBuildLoad(builder_, rtbaseAddr, ""); + return currentSpFrame; +} + +void LLVMIRBuilder::SetCurrentSPFrame(LLVMValueRef sp) +{ + LLVMValueRef addr = GetCurrentSPFrameAddr(); + LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, addr, LLVMPointerType(slotType_, 0), ""); + LLVMBuildStore(builder_, sp, rtbaseAddr); +} + +LLVMValueRef LLVMIRBuilder::GetCurrentFrameType(LLVMValueRef currentSpFrameAddr) +{ + LLVMValueRef tmp = LLVMBuildSub(builder_, currentSpFrameAddr, LLVMConstInt(slotType_, slotSize_, 1), ""); + LLVMValueRef frameTypeAddr = LLVMBuildIntToPtr(builder_, tmp, LLVMPointerType(LLVMInt64Type(), 1), ""); + LLVMValueRef frameType = LLVMBuildLoad(builder_, frameTypeAddr, ""); + return frameType; +} + +void LLVMIRBuilder::PushFrameContext(LLVMValueRef newSp, LLVMValueRef oldSp) +{ + LLVMValueRef optFramePtr = LLVMBuildIntToPtr(builder_, newSp, LLVMPointerType(optFrameType_, 0), ""); + // set frameType + LLVMValueRef typeDices[] = {LLVMConstInt(LLVMInt32Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 0, 0)}; + LLVMValueRef frameTypeAddr = LLVMBuildGEP2(builder_, optFrameType_, + optFramePtr, typeDices, sizeof(typeDices) / sizeof(LLVMValueRef), "getFrameTypeAddr"); + LLVMBuildStore(builder_, LLVMConstInt(LLVMInt64Type(), + static_cast(panda::ecmascript::FrameType::OPTIMIZED_LEAVE_FRAME), 1), + frameTypeAddr); + // set prev + LLVMValueRef prevDices[] = {LLVMConstInt(LLVMInt32Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 1, 0)}; + LLVMValueRef prevTypeAddr = LLVMBuildGEP2(builder_, optFrameType_, + optFramePtr, prevDices, sizeof(prevDices) / sizeof(LLVMValueRef), "getFramePrevAddr"); + LLVMValueRef convertOldSp = LLVMBuildIntToPtr(builder_, oldSp, LLVMPointerType(LLVMInt64Type(), 0), ""); + LLVMBuildStore(builder_, convertOldSp, prevTypeAddr); + // sp + LLVMValueRef spDices[] = {LLVMConstInt(LLVMInt32Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 2, 0)}; + LLVMValueRef spAddr = LLVMBuildGEP2(builder_, optFrameType_, + optFramePtr, spDices, sizeof(spDices) / sizeof(LLVMValueRef), "getFrameSpAddr"); + LLVMValueRef sp = GetCurrentSP(); + LLVMValueRef convertSpAddr = LLVMBuildIntCast2(builder_, sp, slotType_, 1, ""); + LLVMBuildStore(builder_, convertSpAddr, spAddr); + // fp + LLVMValueRef fpDices[] = {LLVMConstInt(LLVMInt32Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 3, 0)}; + LLVMValueRef fpAddr = LLVMBuildGEP2(builder_, optFrameType_, + optFramePtr, fpDices, sizeof(fpDices) / sizeof(LLVMValueRef), "getFrameFpAddr"); + LLVMValueRef fpValue = CallingFp(module_, builder_, false); + LLVMValueRef convertFpValue = LLVMBuildPtrToInt(builder_, fpValue, slotType_, ""); + LLVMBuildStore(builder_, convertFpValue, fpAddr); + // patchpointid + LLVMValueRef patchpointIdDices[] = {LLVMConstInt(LLVMInt32Type(), 0, 0), LLVMConstInt(LLVMInt32Type(), 4, 0)}; + LLVMValueRef patchpointIdAddr = LLVMBuildGEP2(builder_, optFrameType_, + optFramePtr, patchpointIdDices, sizeof(patchpointIdDices) / sizeof(LLVMValueRef), "getFramePatchPointIdAddr"); + LLVMValueRef patchPointIdVlue = LLVMConstInt(LLVMInt64Type(), 2882400000, 0); // 2882400000: default statepoint ID + LLVMBuildStore(builder_, patchPointIdVlue, patchpointIdAddr); +} + +void LLVMIRBuilder::ConstructFrame() +{ + LLVMValueRef currentSp = GetCurrentSPFrame(); + LLVMValueRef newSp = currentSp; + // set newsp:currentSp sub interpretedFrame and optFrame + newSp = LLVMBuildSub(builder_, newSp, LLVMConstInt(slotType_, + optFrameSize_, 1), ""); + newSp = LLVMBuildSub(builder_, newSp, LLVMConstInt(slotType_, + interpretedFrameSize_, 1), ""); + PushFrameContext(newSp, currentSp); + LLVMValueRef preAddr = LLVMBuildAdd(builder_, newSp, LLVMConstInt(slotType_, + optLeaveFramePrevOffset_, 1), "");// newSp sub type size get presize + SetCurrentSPFrame(preAddr); +} + +void LLVMIRBuilder::DestoryFrame() +{ + LLVMValueRef currentSp = GetCurrentSPFrame(); + LLVMValueRef frameType = GetCurrentFrameType(currentSp); + (void)frameType; + LLVMValueRef preAddr = LLVMBuildSub(builder_, currentSp, LLVMConstInt(slotType_, + optLeaveFramePrevOffset_, 1), ""); + preAddr = LLVMBuildAdd(builder_, preAddr, LLVMConstInt(slotType_, + optFrameSize_, 1), ""); + preAddr = LLVMBuildAdd(builder_, preAddr, + LLVMConstInt(slotType_, interpretedFrameSize_, 1), ""); + SetCurrentSPFrame(preAddr); +} void LLVMIRBuilder::VisitCall(GateRef gate, const std::vector &inList) { @@ -499,13 +624,15 @@ void LLVMIRBuilder::VisitCall(GateRef gate, const std::vector &inList) LLVMTypeRef rtfuncTypePtr = LLVMPointerType(rtfuncType, 0); LLVMValueRef glue = gateToLLVMMaps_[inList[2]]; // 2 : 2 means skip two input gates (target glue) LLVMTypeRef glue_type = LLVMTypeOf(glue); + + // runtime case if (callee_descriptor->GetStubKind() == StubDescriptor::CallStubKind::RUNTIME_STUB) { rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::RUNTIME_FUNCTIONS) + - (index - FAST_STUB_MAXCOUNT) * sizeof(uintptr_t), 0); + (index - FAST_STUB_MAXCOUNT) * slotSize_, 0); } else { rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::FAST_STUB_ENTRIES) + - index * sizeof(uintptr_t), 0); + index * slotSize_, 0); } LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, ""); LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, rtbaseoffset, LLVMPointerType(glue_type, 0), ""); @@ -522,8 +649,19 @@ void LLVMIRBuilder::VisitCall(GateRef gate, const std::vector &inList) COMPILER_LOG(ERROR) << "callee nullptr"; return; } - SaveCallerSp(); + if (compCfg_->IsArm32() || compCfg_->IsAArch64() || compCfg_->IsAmd64()) { + // callerid | idx + if (callee_descriptor->GetStubKind() == StubDescriptor::CallStubKind::RUNTIME_STUB) { + ConstructFrame(); + } + } else { + SaveCurrentSP(); + } + gateToLLVMMaps_[gate] = LLVMBuildCall(builder_, callee, params, inList.size() - paraStartIndex, ""); + if (callee_descriptor->GetStubKind() == StubDescriptor::CallStubKind::RUNTIME_STUB) { + DestoryFrame(); + } return; } diff --git a/ecmascript/compiler/llvm_ir_builder.h b/ecmascript/compiler/llvm_ir_builder.h index 4cb317361e..4fbc4edcdc 100644 --- a/ecmascript/compiler/llvm_ir_builder.h +++ b/ecmascript/compiler/llvm_ir_builder.h @@ -224,8 +224,9 @@ private: BasicBlock *EnsureBasicBlock(int id); LLVMValueRef CallingFp(LLVMModuleRef &module, LLVMBuilderRef &builder, bool isCaller); - void SaveCallerSp(); - LLVMValueRef CallerSp(LLVMModuleRef &module, LLVMBuilderRef &builder, + void SaveCurrentSP(); + LLVMValueRef GetCurrentSP(); + LLVMValueRef ReadRegister(LLVMModuleRef &module, LLVMBuilderRef &builder, LLVMMetadataRef meta); void PrologueHandle(LLVMModuleRef &module, LLVMBuilderRef &builder); LLVMBasicBlockRef EnsureBasicBlock(BasicBlock *bb) const; @@ -253,9 +254,14 @@ private: LLVMValueRef PointerAdd(LLVMValueRef baseAddr, LLVMValueRef offset, LLVMTypeRef rep); LLVMValueRef VectorAdd(LLVMValueRef e1Value, LLVMValueRef e2Value, LLVMTypeRef rep); LLVMValueRef CanonicalizeToInt(LLVMValueRef value); - LLVMValueRef CanonicalizeToPtr(LLVMValueRef value); - + LLVMValueRef GetCurrentSPFrame(); + LLVMValueRef GetCurrentSPFrameAddr(); + void SetCurrentSPFrame(LLVMValueRef sp); + LLVMValueRef GetCurrentFrameType(LLVMValueRef currentSpFrameAddr); + void ConstructFrame(); + void PushFrameContext(LLVMValueRef newSp, LLVMValueRef oldSp); + void DestoryFrame(); private: const CompilationConfig *compCfg_ {nullptr}; const std::vector> *schedule_ {nullptr}; @@ -275,6 +281,12 @@ private: std::unordered_map gateToLLVMMaps_; std::unordered_map opCodeHandleMap_; std::set opCodeHandleIgnore; + LLVMTypeRef optFrameType_; + int optFrameSize_; + int slotSize_; + int interpretedFrameSize_; + LLVMTypeRef slotType_; + int optLeaveFramePrevOffset_; }; } // namespace panda::ecmascript::kungfu #endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_LLVM_IR_BUILDER_H diff --git a/ecmascript/compiler/stub.cpp b/ecmascript/compiler/stub.cpp index 96915a60cc..14f8a365be 100644 --- a/ecmascript/compiler/stub.cpp +++ b/ecmascript/compiler/stub.cpp @@ -803,7 +803,7 @@ void Stub::JSObjectSetProperty(GateRef glue, GateRef obj, GateRef hClass, GateRe // compute outOfLineProp offset, get it and return GateRef array = Load(MachineType::TAGGED_POINTER, obj, GetArchRelateConstant(JSObject::PROPERTIES_OFFSET)); SetValueToTaggedArray(MachineType::TAGGED, glue, array, Int32Sub(attrOffset, - GetInt32Constant(GetInlinedPropertiesFromHClass(hClass))), value); + GetInlinedPropertiesFromHClass(hClass)), value); Jump(&exit); } } @@ -921,15 +921,14 @@ void Stub::JSHClassAddProperty(GateRef glue, GateRef receiver, GateRef key, Gate Bind(¬FindHClass); { GateRef type = GetObjectType(hclass); - int32_t defaultCapacity = JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS * JSTaggedValue::TaggedTypeSize(); - GateRef size = Int32Sub(ChangeInt64ToInt32(GetObjectSizeFromHClass(hclass)), - GetInt32Constant(defaultCapacity)); + GateRef size = Int32Mul(GetInlinedPropsStartFromHClass(hclass), + GetInt32Constant(JSTaggedValue::TaggedTypeSize())); + GateRef inlineProps = GetInlinedPropertiesFromHClass(hclass); StubDescriptor *newEcmaDynClass = GET_STUBDESCRIPTOR(NewEcmaDynClass); GateRef newJshclass = CallRuntime(newEcmaDynClass, glue, GetWord64Constant(FAST_STUB_ID(NewEcmaDynClass)), { - glue, size, type + glue, size, type, inlineProps }); CopyAllHClass(glue, newJshclass, hclass); - IncNumberOfProps(glue, newJshclass); StubDescriptor *updateLayout = GET_STUBDESCRIPTOR(UpdateLayOutAndAddTransition); CallRuntime(updateLayout, glue, GetWord64Constant(FAST_STUB_ID(UpdateLayOutAndAddTransition)), { glue, hclass, newJshclass, key, attr @@ -2298,6 +2297,7 @@ void Stub::CopyAllHClass(GateRef glue, GateRef dstHClass, GateRef srcHClass) Bind(&exit); SetPrototypeToHClass(MachineType::TAGGED_POINTER, glue, dstHClass, proto); SetBitFieldToHClass(glue, dstHClass, GetBitFieldFromHClass(srcHClass)); + SetNumberOfPropsToHClass(glue, dstHClass, GetNumberOfPropsFromHClass(srcHClass)); SetParentToHClass(MachineType::INT64, glue, dstHClass, GetWord64Constant(JSTaggedValue::VALUE_NULL)); SetTransitionsToHClass(MachineType::INT64, glue, dstHClass, GetWord64Constant(JSTaggedValue::VALUE_NULL)); SetProtoChangeDetailsToHClass(MachineType::INT64, glue, dstHClass, GetWord64Constant(JSTaggedValue::VALUE_NULL)); diff --git a/ecmascript/compiler/stub.h b/ecmascript/compiler/stub.h index 3b7e5d71e5..9d310bed8a 100644 --- a/ecmascript/compiler/stub.h +++ b/ecmascript/compiler/stub.h @@ -88,14 +88,17 @@ public: offsetTable_ = { GLUE_EXCEPTION_OFFSET_64, GLUE_GLOBAL_CONSTANTS_OFFSET_64, GLUE_PROPERTIES_CACHE_OFFSET_64, GLUE_GLOBAL_STORAGE_OFFSET_64, GLUE_CURRENT_FRAME_OFFSET_64, GLUE_LAST_IFRAME_OFFSET_64, - GLUE_RUNTIME_FUNCTIONS_OFFSET_64, GLUE_FASTSTUB_ENTRIES_OFFSET_64 + GLUE_RUNTIME_FUNCTIONS_OFFSET_64, GLUE_FASTSTUB_ENTRIES_OFFSET_64, GLUE_FRAME_STATE_SIZE_64, + GLUE_OPT_LEAVE_FRAME_SIZE_64, GLUE_OPT_LEAVE_FRAME_PREV_OFFSET_64 + }; break; case Triple::TRIPLE_ARM32: offsetTable_ = { GLUE_EXCEPTION_OFFSET_32, GLUE_GLOBAL_CONSTANTS_OFFSET_32, GLUE_PROPERTIES_CACHE_OFFSET_32, GLUE_GLOBAL_STORAGE_OFFSET_32, GLUE_CURRENT_FRAME_OFFSET_32, GLUE_LAST_IFRAME_OFFSET_32, - GLUE_RUNTIME_FUNCTIONS_OFFSET_32, GLUE_FASTSTUB_ENTRIES_OFFSET_32 + GLUE_RUNTIME_FUNCTIONS_OFFSET_32, GLUE_FASTSTUB_ENTRIES_OFFSET_32, GLUE_FRAME_STATE_SIZE_32, + GLUE_OPT_LEAVE_FRAME_SIZE_32, GLUE_OPT_LEAVE_FRAME_PREV_OFFSET_32 }; break; default: diff --git a/ecmascript/compiler/stub_descriptor.cpp b/ecmascript/compiler/stub_descriptor.cpp index ba7f09dd80..a8bf2fae77 100644 --- a/ecmascript/compiler/stub_descriptor.cpp +++ b/ecmascript/compiler/stub_descriptor.cpp @@ -548,15 +548,16 @@ CALL_STUB_INIT_DESCRIPTOR(NewInternalString) CALL_STUB_INIT_DESCRIPTOR(NewEcmaDynClass) { - // 3 : 3 input parameters - StubDescriptor newEcmaDynClass("NewEcmaDynClass", 0, 3, + // 4 : 4 input parameters + StubDescriptor newEcmaDynClass("NewEcmaDynClass", 0, 4, ArgumentsOrder::DEFAULT_ORDER, MachineType::TAGGED_POINTER); *descriptor = newEcmaDynClass; - // 3 : 3 input parameters - std::array params = { + // 4 : 4 input parameters + std::array params = { MachineType::NATIVE_POINTER, MachineType::UINT32, MachineType::UINT32, + MachineType::UINT32, }; descriptor->SetParameters(params.data()); descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); diff --git a/ecmascript/compiler/tests/stub_tests.cpp b/ecmascript/compiler/tests/stub_tests.cpp index 12a4b6d1be..5f718a1a96 100644 --- a/ecmascript/compiler/tests/stub_tests.cpp +++ b/ecmascript/compiler/tests/stub_tests.cpp @@ -889,13 +889,13 @@ void DoSafepoint() uintptr_t *rsp = rbp + 2; // move 2 steps from rbp to get rsp rbp = reinterpret_cast(*rbp); const ::kungfu::DwarfRegAndOffsetTypeVector *infos = - ::kungfu::LLVMStackMapParser::GetInstance().StackMapByAddr(returnAddr); + ::kungfu::LLVMStackMapParser::GetInstance().GetCallSiteInfoByPc(returnAddr); if (infos != nullptr) { for (auto &info : *infos) { uintptr_t **address = nullptr; - if (info.first == FrameConst::SP_DWARF_REG_NUM) { + if (info.first == FrameCommonConstants::SP_DWARF_REG_NUM) { address = reinterpret_cast(reinterpret_cast(rsp) + info.second); - } else if (info.first == FrameConst::FP_DWARF_REG_NUM) { + } else if (info.first == FrameCommonConstants::FP_DWARF_REG_NUM) { address = reinterpret_cast(reinterpret_cast(rbp) + info.second); } // print ref and vlue for debug diff --git a/ecmascript/frames.h b/ecmascript/frames.h index 285aaed781..b8a5a7283b 100755 --- a/ecmascript/frames.h +++ b/ecmascript/frames.h @@ -13,11 +13,9 @@ * limitations under the License. */ -// in aot project, three Frame: Interpreter Frame、Runtime Frame、Optimized Frame. Optimized Frame split -// Optimized Entry Frame(interpreter call stub) and Optimized Frame(stub call stub) by call scenario. -// ​we gc trigger, we skip Runtime Frame, thus define OPTIMIZED_FRAME、OPTIMIZED_ENTRY_FRAME、 -// INTERPRETER_FRAME respectively -// represent optimized frame、optimized entry frame、interpreter frame. +// in aot project, three Frame: Interpreter Frame、Runtime Frame、Optimized Frame. Optimized Frame +// call Runtime function, generate OptLeaveFrame Frame(gc related context (patchid、sp、fp) is saved to frame) +// then return Optimized thread.sp restore orignal sp. // Frame Layout // Interpreter Frame(alias **iframe** ) Layout as follow: @@ -46,7 +44,7 @@ // | env | | | // |----------------------------------| | | // | acc | | | -// |----------------------------------| FrameState | +// |----------------------------------|InterpretedFrame | // | profileTypeInfo | | | // |----------------------------------| | | // | constantpool | | | @@ -64,95 +62,11 @@ // pre field pointer pre stack frame point. fill JSthread's sp field with iframe sp field // by calling JSThread->SetCurrentSPFrame and save pre Frame address to iframe pre field. -// Runtime Frame: comply with C-ABI without custom modify, function generat frame. -// ​ -// Optimized Frame and Optimized Entry Frame, we also comply with C-ABI, -// the difference from Runtime Frame is that prologue and epilogue is customed. - -// Optimized Entry Frame layout as follow, we reserve two stack slot for saving eparately new field **FrameType** -// which's value is OPTIMIZED_ENTRY_FRAME and -// new field pre that's value is iframe.sp by calling JSThread->GetCurrentSPFrame. -// fp field point to pre frame, **currentfp** is pointer to fp field address. -// save JSthread's sp to pre field and fill JSthread's sp field with **currentfp** . - - -// ``` -// +---------------------------------------------------+ -// | parameter n | ^ -// |- - - - - - - - - -- | | -// | parameter n-1 | Caller frame -// | ... | comply c-abi -// | parameter n-2 | paramters push to stack from left to right -// |- - - - - - - - - | i-n th prameter spill to slot -// | parameter i | v -// +--------------------------+------------------------+ -// | return addr | ^ ^ -// |- - - - - - - - - | | | -// | fp | Fixed | -// |- - - - - - - - - | Header <-- frame ptr | -// | FrameType | | callee frame Header -// |- - - - - - - - - | | | -// | pre | v | -// +--------------------------+------------------------+ -// ``` - -// ​ Optimized Frame layout as follow, we reserve one stack slot for saving FrameType field, -// which's value is OPTIMIZED_FRAME. - -// ``` -// +---------------------------------------------------+ -// | parameter n | ^ -// |- - - - - - - - - -- | | -// | parameter n-1 | Caller frame -// | ... | comply c-abi -// | parameter n-2 | paramters push to stack from left to right -// |- - - - - - - - - | i-n th prameter spill to slot -// | parameter i | v -// +--------------------------+------------------------+ -// | return addr | ^ ^ -// |- - - - - - - - - | | | -// | fp | Fixed | -// |- - - - - - - - - | Header <-- frame ptr callee frame Header -// | FrameType | V | -// +--------------------------+------------------------+ -// ``` - -// ​ JSthread's sp will be updated dynamic, the scenarios is as follows by different Frames: -// **SAVE** is to save JSthread's sp to current Frame pre field, -// **UPDATE** is to fill JSthread's sp with currentsp or currentfp when current frame is iframe -// or Optimized EntryFrame/Optimized Frame. -// **nop** represent don't call SAVE or UPDATE, **illegal** represent this secnarios don't existed. - -// +----------------------------------------------------------------------+ -// | | iframe | OptimizedEntry | Optimized | RunTime | -// |----------------------------------------------------------------------- -// |iframe | SAVE/UPATE | SAVE | illegal | SAVE/UPATE | -// |----------------------------------------------------------------------- -// |OptimizedEntry | UPATE | illegal | nop | UPATE | -// |----------------------------------------------------------------------- -// |Optimized | UPATE | illegal | nop | UPATE | -// |----------------------------------------------------------------------- -// |RunTime | nop | illegal | illegal | nop | -// +----------------------------------------------------------------------+ -// ``` - -// ​ Iterator Frame from Runtime Frame, the process is as flollows: - -// 1 calling JSThread->GetCurrentSPFrame get Current Frame, then get FrameType field - -// 2 Iterator previous Frame: - -// ​ accessing fp field when the current frame is Optimized Frame; - -// ​ accessing pre field when the current frame is Optimized Entry Frame or Interpreter Frame - -// 3 repeat process 2 until Current Frame is nullptr - // For Example: // ``` -// call call call -// foo -----------------> bar --------------->baz---------------------> rtfunc -// (interpret frame) (Optimized Entry Frame) (Optimized Frame) (Runtime Frame) +// call call +// foo -----------------> bar -----------------------> rtfunc +// (interpret frame) (OptLeaveFrame) (Runtime Frame) // ``` // Frame Layout as follow: @@ -178,7 +92,7 @@ // |----------------------------------| | | // | acc | | | // |----------------------------------| | | -// | profileTypeInfo | FrameState | +// | profileTypeInfo |InterpretedFrame | // |----------------------------------| | | // | constantpool | | | // |----------------------------------| | | @@ -190,21 +104,16 @@ // +----------------------------------+--------+----------+ // | ............. | // +--------------------------+---------------------------+ -// | return addr | ^ ^ +// | patchID | ^ ^ // |- - - - - - - - - | | | -// | fp | Fixed | -// |- - - - - - - - - | Header <-- frame ptr | -// | FrameType | | bar's frame Header +// | fp | Fixed | +// |- - - - - - - - - | OptLeaveFrame | +// | sp | | bar's frame Header // |- - - - - - - - - | | | -// | pre | v | -// +--------------------------+---------------------------+ -// | ............. | -// +--------------------------+---------------------------+ -// | return addr | ^ ^ +// | prev | | // |- - - - - - - - - | | | -// | fp | Fixed | -// |- - - - - - - - - | Header <-- frame ptr | -// | FrameType | v baz's frame Header +// | frameType | v | +// +--------------------------+---------------------------+ // | ............. | // +--------------------------+---------------------------+ // | | @@ -213,8 +122,8 @@ // +------------------------------------------------------+ // ``` // Iterator: -// rtfunc get baz's Frame **currentfp** by calling GetCurrentSPFrame. -// baz'Frame fp field point to bar's Frame **currentfp**, then get bar's Frame pre field. +// rtfunc get bar's Frame **currentfp** by calling GetCurrentSPFrame. +// then get bar's Frame pre field. // bar's Frame pre field point to foo's Frame **currentsp**. // finally we can iterator foo's Frame. @@ -223,67 +132,83 @@ #include "ecmascript/js_tagged_value.h" -#ifdef PANDA_TARGET_AMD64 -#define GET_CURRETN_FP(fp) asm("mov %%rbp, %0" : "=rm" (fp)) -#define POINTER_CAST(fp, type) static_cast(static_cast(fp) -#define GET_PREV_FP(fp) reinterpret_cast(*(fp)) -#endif - -#ifdef PANDA_TARGET_ARM64 -#define GET_CURRETN_FP(fp) asm("mov %0, x29" : "=r" (fp)) -#define POINTER_CAST(fp, type) static_cast(static_cast(fp)) -#define GET_PREV_FP(fp) reinterpret_cast(*(POINTER_CAST(fp, uintptr_t *))) -#endif - -#ifdef PANDA_TARGET_ARM32 -#define GET_CURRETN_FP(fp) asm("mov %0, r11" : "=r" (fp)) -#define POINTER_CAST(fp, type) static_cast(static_cast(fp)) -#define GET_PREV_FP(fp) reinterpret_cast(*(POINTER_CAST(fp, uintptr_t *))) -#endif - -#if !defined(PANDA_TARGET_AMD64) && !defined(PANDA_TARGET_ARM64) && !defined(PANDA_TARGET_ARM32) -#define GET_CURRETN_FP(fp) -#define POINTER_CAST(fp, type) static_cast(static_cast(fp)) -#define GET_PREV_FP(fp) reinterpret_cast(*(POINTER_CAST(fp, uintptr_t *))) -#endif - namespace panda::ecmascript { class JSThread; -enum class FrameType: uintptr_t { +enum class FrameType: uint64_t { OPTIMIZED_FRAME = 0, OPTIMIZED_ENTRY_FRAME = 1, INTERPRETER_FRAME = 2, + OPTIMIZED_LEAVE_FRAME = 3, }; -class OptimizedFrameStateBase { +class OptimizedFrame { public: - uintptr_t frameType; + OptimizedFrame() = default; + ~OptimizedFrame() = default; + uint64_t frameType; JSTaggedType *prev; // for llvm :c-fp ; for interrupt: thread-fp for gc - static size_t GetFrameStateOffsetFromSp() + static OptimizedFrame * GetFrameFromSp(panda::ecmascript::JSTaggedType *sp) { - return MEMBER_OFFSET(OptimizedFrameStateBase, prev); + return reinterpret_cast(reinterpret_cast(sp) + - MEMBER_OFFSET(OptimizedFrame, prev)); } }; -class InterpretedFrameStateBase { +class InterpretedFrameBase { public: + InterpretedFrameBase() = default; + ~InterpretedFrameBase() = default; JSTaggedType *prev; // for llvm :c-fp ; for interrupt: thread-fp for gc - uintptr_t frameType; + uint64_t frameType; }; -class OptimizedEntryFrameState { +class OptimizedEntryFrame { public: + OptimizedEntryFrame() = default; + ~OptimizedEntryFrame() = default; JSTaggedType *threadFp; // for gc - OptimizedFrameStateBase base; - static size_t GetFrameStateOffsetFromSp() + OptimizedFrame base; + static OptimizedEntryFrame* GetFrameFromSp(panda::ecmascript::JSTaggedType *sp) + { + return reinterpret_cast(reinterpret_cast(sp) - + MEMBER_OFFSET(OptimizedEntryFrame, base.prev)); + } +}; + +// align with 8 +// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) +struct InterpretedFrame { + const uint8_t *pc; + JSTaggedType *sp; + // aligned with 8 bits + alignas(sizeof(uint64_t)) JSTaggedValue constpool; + JSTaggedValue function; + JSTaggedValue profileTypeInfo; + JSTaggedValue acc; + JSTaggedValue env; + InterpretedFrameBase base; + static InterpretedFrame * GetFrameFromSp(panda::ecmascript::JSTaggedType *sp) + { + return reinterpret_cast(sp) - 1; + } +}; + +struct OptLeaveFrame { + uint64_t frameType; + JSTaggedType *prev; // set cursp here + uintptr_t sp; + uintptr_t fp; + uint64_t patchId; + static OptLeaveFrame* GetFrameFromSp(panda::ecmascript::JSTaggedType *sp) { - return MEMBER_OFFSET(OptimizedEntryFrameState, base.prev); + return reinterpret_cast(reinterpret_cast(sp) - + MEMBER_OFFSET(OptLeaveFrame, prev)); } }; -class FrameConst { +class FrameCommonConstants { public: - static constexpr size_t FRAME_TYPE_OFFSET = -sizeof(uintptr_t); + static constexpr size_t FRAME_TYPE_OFFSET = -sizeof(uint64_t); #ifdef PANDA_TARGET_AMD64 static constexpr int SP_DWARF_REG_NUM = 7; static constexpr int FP_DWARF_REG_NUM = 6; diff --git a/ecmascript/interpreter/frame_handler.cpp b/ecmascript/interpreter/frame_handler.cpp index 6ee27b9d73..66774a9851 100755 --- a/ecmascript/interpreter/frame_handler.cpp +++ b/ecmascript/interpreter/frame_handler.cpp @@ -47,6 +47,12 @@ void FrameHandler::PrevFrame() framehandle->PrevFrame(); break; } + case FrameType::OPTIMIZED_LEAVE_FRAME: { + auto framehandle = + reinterpret_cast(this); + framehandle->PrevFrame(); + break; + } default: UNREACHABLE(); } @@ -61,7 +67,7 @@ void InterpretedFrameHandler::PrevFrame() { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); sp_ = state->base.prev; } @@ -75,7 +81,7 @@ InterpretedFrameHandler InterpretedFrameHandler::GetPrevFrame() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); return InterpretedFrameHandler(state->base.prev); } @@ -97,7 +103,7 @@ JSTaggedValue InterpretedFrameHandler::GetAcc() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); return state->acc; } @@ -105,7 +111,7 @@ uint32_t InterpretedFrameHandler::GetSize() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); JSTaggedType *prevSp = state->base.prev; ASSERT(prevSp != nullptr); auto size = (prevSp - sp_) - FRAME_STATE_SIZE; @@ -116,7 +122,7 @@ uint32_t InterpretedFrameHandler::GetBytecodeOffset() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget(); auto offset = state->pc - method->GetBytecodeArray(); return static_cast(offset); @@ -126,7 +132,7 @@ JSMethod *InterpretedFrameHandler::GetMethod() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); return ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget(); } @@ -134,7 +140,7 @@ JSTaggedValue InterpretedFrameHandler::GetFunction() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); return state->function; } @@ -142,7 +148,7 @@ const uint8_t *InterpretedFrameHandler::GetPc() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); return state->pc; } @@ -150,7 +156,7 @@ JSTaggedType *InterpretedFrameHandler::GetSp() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); return state->sp; } @@ -158,7 +164,7 @@ ConstantPool *InterpretedFrameHandler::GetConstpool() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); return ConstantPool::Cast(state->constpool.GetTaggedObject()); } @@ -166,7 +172,7 @@ JSTaggedValue InterpretedFrameHandler::GetEnv() const { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); return state->env; } @@ -175,12 +181,12 @@ void InterpretedFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisi JSTaggedType *current = sp_; if (current != nullptr) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(current) - 1; + InterpretedFrame *state = reinterpret_cast(current) - 1; if (state->sp != nullptr) { uintptr_t start = ToUintPtr(current); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *prev_state = reinterpret_cast(state->base.prev) - 1; + InterpretedFrame *prev_state = reinterpret_cast(state->base.prev) - 1; uintptr_t end = ToUintPtr(prev_state); v1(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end)); v0(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&state->function))); @@ -218,20 +224,19 @@ void InterpretedFrameHandler::DumpPC(std::ostream &os, const uint8_t *pc) const void OptimizedFrameHandler::PrevFrame() { - OptimizedFrameStateBase *state = reinterpret_cast( - reinterpret_cast(sp_) - OptimizedFrameStateBase::GetFrameStateOffsetFromSp()); + OptimizedFrame *state = OptimizedFrame::GetFrameFromSp(sp_); sp_ = reinterpret_cast(state->prev); } void OptimizedFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1, - ChunkVector *derivedPointers, bool isVerifying) const + ChunkMap *derivedPointers, bool isVerifying) const { - if (fp_ != nullptr) { + if (sp_ != nullptr) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) std::set slotAddrs; - auto returnAddr = reinterpret_cast(*(fp_ + 1)); - bool ret = ::kungfu::LLVMStackMapParser::GetInstance().StackMapByFuncAddrFp( - returnAddr, reinterpret_cast(fp_), v0, v1, derivedPointers, isVerifying); + auto returnAddr = reinterpret_cast(*(reinterpret_cast(sp_) + 1)); + bool ret = ::kungfu::LLVMStackMapParser::GetInstance().GetStackMapIterm( + returnAddr, reinterpret_cast(sp_), v0, v1, derivedPointers, isVerifying); if (ret == false) { #ifndef NDEBUG LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << returnAddr; @@ -241,78 +246,81 @@ void OptimizedFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisito } } -void OptimizedEntryFrameHandler::PrevFrame() -{ - OptimizedEntryFrameState *state = reinterpret_cast( - reinterpret_cast(sp_) - OptimizedEntryFrameState::GetFrameStateOffsetFromSp()); - sp_ = reinterpret_cast(state->threadFp); -} - -void FrameIterator::HandleRuntimeTrampolines(const RootVisitor &v0, const RootRangeVisitor &v1, - ChunkVector *derivedPointers, bool isVerifying) const +void OptimizedEntryFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1, + ChunkMap *derivedPointers, bool isVerifying) const { - if (thread_) { - uintptr_t *fp = thread_->GetLastOptCallRuntimePc(); - if (fp == nullptr) { - return; - } + if (sp_ != nullptr) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) std::set slotAddrs; - auto returnAddr = *(fp + 1); -#ifndef NDEBUG - uintptr_t *optFp = reinterpret_cast(*fp); - auto type = *(optFp - 1); - LOG_ECMA(INFO) << __FUNCTION__ << " returnAddr :" << std::hex << returnAddr << " fp: " << fp << " type:" << - static_cast(type) << std::endl; -#endif - bool ret = ::kungfu::LLVMStackMapParser::GetInstance().StackMapByFuncAddrFp( - returnAddr, reinterpret_cast(fp), v0, v1, derivedPointers, isVerifying); + auto returnAddr = reinterpret_cast(*(reinterpret_cast(sp_) + 1)); + bool ret = ::kungfu::LLVMStackMapParser::GetInstance().GetStackMapIterm( + returnAddr, reinterpret_cast(sp_), v0, v1, derivedPointers, isVerifying); if (ret == false) { #ifndef NDEBUG - LOG_ECMA(INFO) << " stackmap don't found returnAddr " << std::endl; + LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << returnAddr; #endif return; } - for (auto &address: slotAddrs) { + } +} + +void OptimizedEntryFrameHandler::PrevFrame() +{ + OptimizedEntryFrame *state = OptimizedEntryFrame::GetFrameFromSp(sp_); + sp_ = reinterpret_cast(state->threadFp); +} + +void OptimizedLeaveFrameHandler::PrevFrame() +{ + OptLeaveFrame *state = reinterpret_cast( + reinterpret_cast(sp_) - MEMBER_OFFSET(OptLeaveFrame, prev)); + sp_ = reinterpret_cast(state->prev); +} + +void OptimizedLeaveFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1, + ChunkMap *derivedPointers, bool isVerifying) const +{ + OptLeaveFrame *state = reinterpret_cast( + reinterpret_cast(sp_) - MEMBER_OFFSET(OptLeaveFrame, prev)); + bool ret = ::kungfu::LLVMStackMapParser::GetInstance().GetStackMapIterm( + state, v0, v1, derivedPointers, isVerifying); + if (ret == false) { #ifndef NDEBUG - LOG_ECMA(INFO) << "stackmap address : " << std::hex << address << std::endl; + LOG_ECMA(DEBUG) << " stackmap don't found patchPointId " << state->patchId; #endif - v0(Root::ROOT_FRAME, ObjectSlot(address)); - } + return; } } - void FrameIterator::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) const { - ChunkVector *derivedPointers = thread_->GetEcmaVM()->GetHeap()->GetDerivedPointers(); + ChunkMap *derivedPointers = thread_->GetEcmaVM()->GetHeap()->GetDerivedPointers(); bool isVerifying = false; #if ECMASCRIPT_ENABLE_HEAP_VERIFY isVerifying = thread_->GetEcmaVM()->GetHeap()->GetIsVerifying(); #endif - // handle runtimeTrampolines Frame in order get stub returnAddress which used by - // stackMap - HandleRuntimeTrampolines(v0, v1, derivedPointers, isVerifying); - JSTaggedType *current = fp_; + JSTaggedType *current = const_cast(thread_->GetCurrentSPFrame()); while (current) { FrameType type = FrameHandler(current).GetFrameType(); if (type == FrameType::INTERPRETER_FRAME) { - FrameState *state = reinterpret_cast(current) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(current); InterpretedFrameHandler(current).Iterate(v0, v1); current = state->base.prev; } else if (type == FrameType::OPTIMIZED_FRAME) { - OptimizedFrameStateBase *state = reinterpret_cast( - reinterpret_cast(current) - - MEMBER_OFFSET(OptimizedFrameStateBase, prev)); + OptimizedFrame *state = OptimizedFrame::GetFrameFromSp(current); OptimizedFrameHandler(reinterpret_cast(current)).Iterate(v0, v1, derivedPointers, isVerifying); current = reinterpret_cast(state->prev); + } else if (type == FrameType::OPTIMIZED_ENTRY_FRAME) { + OptimizedEntryFrame *state = OptimizedEntryFrame::GetFrameFromSp(current); + current = reinterpret_cast(state->threadFp); } else { - ASSERT(type == FrameType::OPTIMIZED_ENTRY_FRAME); - OptimizedEntryFrameState *state = reinterpret_cast( - reinterpret_cast(current) - - MEMBER_OFFSET(OptimizedEntryFrameState, base.prev)); - current = reinterpret_cast(state->threadFp); + ASSERT(type == FrameType::OPTIMIZED_LEAVE_FRAME); + OptLeaveFrame *state = OptLeaveFrame::GetFrameFromSp(current); + OptimizedLeaveFrameHandler(reinterpret_cast(current)).Iterate(v0, + v1, derivedPointers, isVerifying); + current = reinterpret_cast(state->prev); } } } diff --git a/ecmascript/interpreter/frame_handler.h b/ecmascript/interpreter/frame_handler.h index 15b9cef4c9..eebf1d869a 100644 --- a/ecmascript/interpreter/frame_handler.h +++ b/ecmascript/interpreter/frame_handler.h @@ -44,7 +44,7 @@ public: { ASSERT(HasFrame()); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp_) - 1; + InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_); return state->sp == nullptr; } void PrevFrame(); @@ -53,13 +53,15 @@ public: { ASSERT(HasFrame()); FrameType type = *(reinterpret_cast( - reinterpret_cast(sp_) + FrameConst::FRAME_TYPE_OFFSET)); + reinterpret_cast(sp_) + FrameCommonConstants::FRAME_TYPE_OFFSET)); return type; } private: friend class InterpretedFrameHandler; friend class OptimizedFrameHandler; friend class OptimizedEntryFrameHandler; + friend class OptimizedLeaveFrameHandler; +protected: JSTaggedType *sp_ {nullptr}; }; @@ -103,38 +105,48 @@ public: class OptimizedFrameHandler : public FrameHandler { public: - explicit OptimizedFrameHandler(uintptr_t *fp) - : FrameHandler(reinterpret_cast(fp)), fp_(fp) {} + explicit OptimizedFrameHandler(uintptr_t *sp) + : FrameHandler(reinterpret_cast(sp)) {} explicit OptimizedFrameHandler(const JSThread *thread); ~OptimizedFrameHandler() = default; void PrevFrame(); - void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1, ChunkVector *derivedPointers, + void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1, + ChunkMap *derivedPointers, bool isVerifying) const; -private: - uintptr_t *fp_ {nullptr}; }; class OptimizedEntryFrameHandler : public FrameHandler { public: - explicit OptimizedEntryFrameHandler(uintptr_t *fp) - : FrameHandler(reinterpret_cast(fp)), fp_(fp) {} + explicit OptimizedEntryFrameHandler(uintptr_t *sp) + : FrameHandler(reinterpret_cast(sp)) {} explicit OptimizedEntryFrameHandler(const JSThread *thread); ~OptimizedEntryFrameHandler() = default; void PrevFrame(); -private: - uintptr_t *fp_ {nullptr}; + void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1, + ChunkMap *derivedPointers, + bool isVerifying) const; +}; + +class OptimizedLeaveFrameHandler : public FrameHandler { +public: + explicit OptimizedLeaveFrameHandler(uintptr_t *sp) + : FrameHandler(reinterpret_cast(sp)) {} + explicit OptimizedLeaveFrameHandler(const JSThread *thread); + ~OptimizedLeaveFrameHandler() = default; + void PrevFrame(); + void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1, + ChunkMap *derivedPointers, + bool isVerifying) const; }; class FrameIterator { public: - explicit FrameIterator(JSTaggedType *fp, const JSThread *thread) : fp_(fp), thread_(thread) {} + explicit FrameIterator(JSTaggedType *sp, const JSThread *thread) : sp_(sp), thread_(thread) {} ~FrameIterator() = default; void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) const; - void HandleRuntimeTrampolines(const RootVisitor &v0, const RootRangeVisitor &v1, - ChunkVector *derivedPointers, bool isVerifying) const; void IterateStackMapAfterGC() const; private: - JSTaggedType *fp_ {nullptr}; + JSTaggedType *sp_ {nullptr}; const JSThread *thread_ {nullptr}; }; } // namespace ecmascript diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index ec192a9a30..64dc9ec9f7 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -78,7 +78,7 @@ namespace panda::ecmascript { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define GET_FRAME(CurrentSp) \ - (reinterpret_cast(CurrentSp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + (reinterpret_cast(CurrentSp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define SAVE_PC() (GET_FRAME(sp)->pc = pc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -207,24 +207,26 @@ namespace panda::ecmascript { #define GET_ACC() (acc) // NOLINT(cppcoreguidelines-macro-usage) #define SET_ACC(val) (acc = val); // NOLINT(cppcoreguidelines-macro-usage) -JSTaggedType *EcmaInterpreter::GetCurrentInterpretedFrameSp(JSThread *thread) +JSTaggedType * EcmaInterpreter::FixSpIfNeed(JSThread *thread) { - JSTaggedType *originalPrevSp = const_cast(thread->GetCurrentSPFrame()); - auto current = originalPrevSp; + JSTaggedType *current = const_cast(thread->GetCurrentSPFrame()); FrameType type = *(reinterpret_cast( - reinterpret_cast(current) + FrameConst::FRAME_TYPE_OFFSET)); - JSTaggedType *sp = originalPrevSp; - if (type != FrameType::INTERPRETER_FRAME) { - JSTaggedType *lastSp = const_cast(thread->GetLastInterpretedFrameSp()); - sp = lastSp; - } - return sp; + reinterpret_cast(current) + FrameCommonConstants::FRAME_TYPE_OFFSET)); + if (type == FrameType::INTERPRETER_FRAME) { + return current; + } else if (type == FrameType::OPTIMIZED_LEAVE_FRAME) { + return reinterpret_cast(OptLeaveFrame::GetFrameFromSp(current)); + } else { + abort(); + } + return nullptr; } JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& params) { INTERPRETER_TRACE(thread, ExecuteNative); - JSTaggedType *sp = GetCurrentInterpretedFrameSp(thread); + JSTaggedType *originalPrevSp = const_cast(thread->GetCurrentSPFrame()); + JSTaggedType *fixedSp = FixSpIfNeed(thread); JSMethod *methodToCall = params.callTarget->GetCallTarget(); ASSERT(methodToCall->GetNumVregs() == 0); @@ -232,7 +234,7 @@ JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& // Tags and values of thread, new_tgt and argv_length are put into frames too for native frames // NOLINTNEXTLINE(hicpp-signed-bitwise) size_t frameSize = FRAME_STATE_SIZE + numActualArgs; - JSTaggedType *newSp = sp - frameSize; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + JSTaggedType *newSp = fixedSp - frameSize; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) { return JSTaggedValue::Undefined(); } @@ -246,8 +248,8 @@ JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& newSp[i + RESERVED_CALL_ARGCOUNT] = params.argv[i]; } - FrameState *state = GET_FRAME(newSp); - state->base.prev = sp; + InterpretedFrame *state = GET_FRAME(newSp); + state->base.prev = originalPrevSp; state->base.frameType = static_cast(FrameType::INTERPRETER_FRAME); state->pc = nullptr; state->sp = newSp; @@ -261,7 +263,7 @@ JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& JSTaggedValue tagged = reinterpret_cast(const_cast(methodToCall->GetNativePointer()))(&ecmaRuntimeCallInfo); LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call."; - thread->SetCurrentSPFrame(sp); + thread->SetCurrentSPFrame(originalPrevSp); #if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER CpuProfiler::IsNeedAndGetStack(thread); #endif @@ -277,15 +279,14 @@ JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& param return EcmaInterpreter::ExecuteNative(thread, params); } JSTaggedType *originalPrevSp = const_cast(thread->GetCurrentSPFrame()); - - JSTaggedType *sp = GetCurrentInterpretedFrameSp(thread); - JSTaggedType *newSp = sp - FRAME_STATE_SIZE; + JSTaggedType *fixedSp = FixSpIfNeed(thread); + JSTaggedType *newSp = fixedSp - FRAME_STATE_SIZE; // push break state // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) { return JSTaggedValue::Undefined(); } - FrameState *breakState = GET_FRAME(newSp); + InterpretedFrame *breakState = GET_FRAME(newSp); breakState->pc = nullptr; breakState->sp = nullptr; breakState->function = JSTaggedValue::Hole(); @@ -356,7 +357,7 @@ JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& param } const uint8_t *pc = method->GetBytecodeArray(); - FrameState *state = GET_FRAME(newSp); + InterpretedFrame *state = GET_FRAME(newSp); state->pc = pc; state->sp = newSp; state->function = JSTaggedValue(params.callTarget); @@ -405,7 +406,7 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH if (thread->DoStackOverflowCheck(breakSp) || thread->HasPendingException()) { return JSTaggedValue::Exception(); } - FrameState *breakState = GET_FRAME(breakSp); + InterpretedFrame *breakState = GET_FRAME(breakSp); breakState->pc = nullptr; breakState->sp = nullptr; breakState->function = JSTaggedValue::Hole(); @@ -431,7 +432,7 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH const uint8_t *resumePc = method->GetBytecodeArray() + static_cast(pcOffset.GetInt()) + BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8); - FrameState *state = GET_FRAME(newSp); + InterpretedFrame *state = GET_FRAME(newSp); state->pc = resumePc; state->sp = newSp; state->function = func.GetTaggedValue(); @@ -467,7 +468,7 @@ void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandleDoStackOverflowCheck(breakSp) || thread->HasPendingException()) { return; } - FrameState *breakState = GET_FRAME(breakSp); + InterpretedFrame *breakState = GET_FRAME(breakSp); breakState->pc = nullptr; breakState->sp = nullptr; breakState->function = JSTaggedValue::Hole(); @@ -493,7 +494,7 @@ void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandleGetBytecodeArray() + static_cast(pcOffset.GetInt()); - FrameState *state = GET_FRAME(newSp); + InterpretedFrame *state = GET_FRAME(newSp); state->pc = pc; state->sp = newSp; state->function = func.GetTaggedValue(); @@ -511,7 +512,7 @@ void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandle(thread->GetCurrentSPFrame()); - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); thread->SetCurrentSPFrame(state->base.prev); } @@ -844,7 +845,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } } - FrameState *state = GET_FRAME(newSp); + InterpretedFrame *state = GET_FRAME(newSp); state->base.prev = sp; state->base.frameType = static_cast(FrameType::INTERPRETER_FRAME); state->pc = nullptr; @@ -991,7 +992,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool InterpreterFrameCopyArgs(newSp, numVregs, copyArgs, numDeclaredArgs, haveExtra); } - FrameState *state = GET_FRAME(newSp); + InterpretedFrame *state = GET_FRAME(newSp); state->base.prev = sp; state->base.frameType = static_cast(FrameType::INTERPRETER_FRAME); state->pc = pc = JSMethod::Cast(methodToCall)->GetBytecodeArray(); @@ -1013,7 +1014,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } HANDLE_OPCODE(HANDLE_RETURN_DYN) { LOG_INST() << "returnla "; - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast(state->sp) << " " << std::hex << reinterpret_cast(state->pc); JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget(); @@ -1021,7 +1022,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool UPDATE_HOTNESS_COUNTER(-(pc - fistPC)); sp = state->base.prev; ASSERT(sp != nullptr); - FrameState *prevState = GET_FRAME(sp); + InterpretedFrame *prevState = GET_FRAME(sp); pc = prevState->pc; // break frame @@ -1038,7 +1039,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } HANDLE_OPCODE(HANDLE_RETURNUNDEFINED_PREF) { LOG_INST() << "return.undefined"; - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast(sp) << " " << std::hex << reinterpret_cast(state->pc); JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget(); @@ -1046,7 +1047,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool UPDATE_HOTNESS_COUNTER_NON_ACC(-(pc - fistPC)); sp = state->base.prev; ASSERT(sp != nullptr); - FrameState *prevState = GET_FRAME(sp); + InterpretedFrame *prevState = GET_FRAME(sp); pc = prevState->pc; // break frame @@ -1109,7 +1110,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } HANDLE_OPCODE(HANDLE_LDLEXENVDYN_PREF) { LOG_INST() << "intrinsics::ldlexenvDyn "; - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); JSTaggedValue currentLexenv = state->env; SET_ACC(currentLexenv); DISPATCH(BytecodeInstruction::Format::PREF_NONE); @@ -1250,11 +1251,11 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } HANDLE_OPCODE(HANDLE_TYPEOFDYN_PREF) { LOG_INST() << "intrinsics::typeofdyn"; -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(FastTypeOf)); - typedef JSTaggedType (*PFFastTypeOf)(uintptr_t, JSTaggedValue); + typedef JSTaggedType (*PFFastTypeOf)(uintptr_t, JSTaggedType); auto fastTypeOfPtr = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(fastTypeOfPtr(thread->GetGlueAddr(), GET_ACC())); + JSTaggedValue res = JSTaggedValue(fastTypeOfPtr(thread->GetGlueAddr(), GET_ACC().GetRawData())); #else JSTaggedValue res = FastRuntimeStub::FastTypeOf(thread, GET_ACC()); #endif @@ -1417,9 +1418,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue right = acc; #ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(FastMul)); - typedef JSTaggedType (*PFFastMul)(JSTaggedValue, JSTaggedValue); + typedef JSTaggedType (*PFFastMul)(JSTaggedType, JSTaggedType); auto fastMulPtr = reinterpret_cast(stubAddr); - JSTaggedValue value = JSTaggedValue(fastMulPtr(left, right)); + JSTaggedValue value = JSTaggedValue(fastMulPtr(left.GetRawData(), right.GetRawData())); #else JSTaggedValue value = FastRuntimeStub::FastMul(left, right); #endif @@ -1458,11 +1459,11 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue left = GET_VREG_VALUE(vs); JSTaggedValue right = GET_ACC(); -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(FastMod)); - typedef JSTaggedType (*PFFastMod)(uintptr_t, JSTaggedValue, JSTaggedValue); + typedef JSTaggedType (*PFFastMod)(uintptr_t, JSTaggedType, JSTaggedType); auto fastModPtr = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(fastModPtr(thread->GetGlueAddr(), left, right)); + JSTaggedValue res = JSTaggedValue(fastModPtr(thread->GetGlueAddr(), left.GetRawData(), right.GetRawData())); #else JSTaggedValue res = FastRuntimeStub::FastMod(left, right); #endif @@ -1483,11 +1484,11 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool << " v" << v0; JSTaggedValue left = GET_VREG_VALUE(v0); JSTaggedValue right = acc; -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(FastEqual)); - typedef JSTaggedType (*PFFastEqual)(JSTaggedValue, JSTaggedValue); + typedef JSTaggedType (*PFFastEqual)(JSTaggedType, JSTaggedType); auto fastEqualPtr = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(fastEqualPtr(left, right)); + JSTaggedValue res = JSTaggedValue(fastEqualPtr(left.GetRawData(), right.GetRawData())); #else JSTaggedValue res = FastRuntimeStub::FastEqual(left, right); #endif @@ -2017,7 +2018,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool LOG_INST() << "intrinsics::ldlexvardyn" << " level:" << level << " slot:" << slot; - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); JSTaggedValue currentLexenv = state->env; JSTaggedValue env(currentLexenv); for (int i = 0; i < level; i++) { @@ -2034,7 +2035,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool LOG_INST() << "intrinsics::ldlexvardyn" << " level:" << level << " slot:" << slot; - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); JSTaggedValue currentLexenv = state->env; JSTaggedValue env(currentLexenv); for (int i = 0; i < level; i++) { @@ -2051,7 +2052,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool LOG_INST() << "intrinsics::ldlexvardyn" << " level:" << level << " slot:" << slot; - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); JSTaggedValue currentLexenv = state->env; JSTaggedValue env(currentLexenv); for (int i = 0; i < level; i++) { @@ -2070,7 +2071,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool << " level:" << level << " slot:" << slot << " v" << v0; JSTaggedValue value = GET_VREG_VALUE(v0); - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); JSTaggedValue env = state->env; for (int i = 0; i < level; i++) { JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv(); @@ -2089,7 +2090,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool << " level:" << level << " slot:" << slot << " v" << v0; JSTaggedValue value = GET_VREG_VALUE(v0); - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); JSTaggedValue env = state->env; for (int i = 0; i < level; i++) { JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv(); @@ -2108,7 +2109,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool << " level:" << level << " slot:" << slot << " v" << v0; JSTaggedValue value = GET_VREG_VALUE(v0); - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); JSTaggedValue env = state->env; for (int i = 0; i < level; i++) { JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv(); @@ -2134,7 +2135,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool DISPATCH(BytecodeInstruction::Format::PREF_IMM16); } HANDLE_OPCODE(HANDLE_POPLEXENVDYN_PREF) { - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); JSTaggedValue currentLexenv = state->env; JSTaggedValue parentLexenv = LexicalEnv::Cast(currentLexenv.GetTaggedObject())->GetParentEnv(); GET_FRAME(sp)->env = parentLexenv; @@ -2166,7 +2167,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget(); [[maybe_unused]] auto fistPC = method->GetInstructions(); UPDATE_HOTNESS_COUNTER(-(pc - fistPC)); @@ -2174,7 +2175,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool << std::hex << reinterpret_cast(state->pc); sp = state->base.prev; ASSERT(sp != nullptr); - FrameState *prevState = GET_FRAME(sp); + InterpretedFrame *prevState = GET_FRAME(sp); pc = prevState->pc; // break frame @@ -2268,11 +2269,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue value = GET_ACC(); // fast path SAVE_ACC(); -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByNameWithOwn)); - typedef JSTaggedType (*PFSetPropertyByName)(uintptr_t, JSTaggedValue, JSTaggedValue, JSTaggedValue); + typedef JSTaggedType (*PFSetPropertyByName)(uintptr_t, JSTaggedType, JSTaggedType, JSTaggedType); auto setPropertyByNamePtr = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(setPropertyByNamePtr(thread->GetGlueAddr(), receiver, propKey, value)); + JSTaggedValue res = JSTaggedValue(setPropertyByNamePtr(thread->GetGlueAddr(), + receiver.GetRawData(), propKey.GetRawData(), value.GetRawData())); #else JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value); #endif @@ -2601,11 +2603,11 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue receiver = GET_VREG_VALUE(v0); // fast path if (LIKELY(receiver.IsHeapObject())) { -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByIndex)); - typedef JSTaggedType (*PFGetPropertyByIndex)(uintptr_t, JSTaggedValue, uint32_t); + typedef JSTaggedType (*PFGetPropertyByIndex)(uintptr_t, JSTaggedType, uint32_t); auto getPropertyByIndex = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(getPropertyByIndex(thread->GetGlueAddr(), receiver, idx)); + JSTaggedValue res = JSTaggedValue(getPropertyByIndex(thread->GetGlueAddr(), receiver.GetRawData(), idx)); #else JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, receiver, idx); #endif @@ -2633,11 +2635,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool SAVE_ACC(); JSTaggedValue value = GET_ACC(); // fast path -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByIndex)); - typedef JSTaggedType (*PFSetPropertyByIndex)(uintptr_t, JSTaggedValue, uint32_t, JSTaggedValue); + typedef JSTaggedType (*PFSetPropertyByIndex)(uintptr_t, JSTaggedType, uint32_t, JSTaggedType); auto setPropertyByIndex = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(setPropertyByIndex(thread->GetGlueAddr(), receiver, index, value)); + JSTaggedValue res = JSTaggedValue(setPropertyByIndex(thread->GetGlueAddr(), + receiver.GetRawData(), index, value.GetRawData())); #else JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value); #endif @@ -2694,11 +2697,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool #endif // fast path if (LIKELY(receiver.IsHeapObject())) { -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByValue)); - typedef JSTaggedType (*PFGetPropertyByValue)(uintptr_t, JSTaggedValue, JSTaggedValue); + typedef JSTaggedType (*PFGetPropertyByValue)(uintptr_t, JSTaggedType, JSTaggedType); auto getPropertyByValuePtr = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(getPropertyByValuePtr(thread->GetGlueAddr(), receiver, propKey)); + JSTaggedValue res = JSTaggedValue(getPropertyByValuePtr(thread->GetGlueAddr(), + receiver.GetRawData(), propKey.GetRawData())); #else JSTaggedValue res = FastRuntimeStub::GetPropertyByValue(thread, receiver, propKey); #endif @@ -2987,11 +2991,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue value = GET_ACC(); // fast path SAVE_ACC(); -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByNameWithOwn)); - typedef JSTaggedType (*PFSetPropertyByName)(uintptr_t, JSTaggedValue, JSTaggedValue, JSTaggedValue); + typedef JSTaggedType (*PFSetPropertyByName)(uintptr_t, JSTaggedType, JSTaggedType, JSTaggedType); auto setPropertyByNamePtr = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(setPropertyByNamePtr(thread->GetGlueAddr(), receiver, propKey, value)); + JSTaggedValue res = JSTaggedValue(setPropertyByNamePtr(thread->GetGlueAddr(), receiver.GetRawData(), + propKey.GetRawData(), value.GetRawData())); #else JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value); #endif @@ -3083,11 +3088,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool if (LIKELY(receiver.IsHeapObject())) { // fast path -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByName)); - typedef JSTaggedType (*PFGetPropertyByName)(uintptr_t, JSTaggedValue, JSTaggedValue); + typedef JSTaggedType (*PFGetPropertyByName)(uintptr_t, JSTaggedType, JSTaggedType); auto getPropertyByNamePtr = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(getPropertyByNamePtr(thread->GetGlueAddr(), receiver, propKey)); + JSTaggedValue res = JSTaggedValue(getPropertyByNamePtr(thread->GetGlueAddr(), receiver.GetRawData(), + propKey.GetRawData())); #else JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, receiver, propKey); #endif @@ -3120,13 +3126,14 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool if (LIKELY(firstValue.IsHeapObject())) { JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1); -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(TryStoreICByName)); typedef JSTaggedType (*PFTryStoreICByName)(uintptr_t, - JSTaggedValue, JSTaggedValue, JSTaggedValue, JSTaggedValue); + JSTaggedType, JSTaggedType, JSTaggedType, JSTaggedType); auto tryStoreICByNamePtr = reinterpret_cast(stubAddr); res = JSTaggedValue( - tryStoreICByNamePtr(thread->GetGlueAddr(), receiver, firstValue, secondValue, value)); + tryStoreICByNamePtr(thread->GetGlueAddr(), receiver.GetRawData(), + firstValue.GetRawData(), secondValue.GetRawData(), value.GetRawData())); #else res = ICRuntimeStub::TryStoreICByName(thread, receiver, firstValue, secondValue, value); #endif @@ -3155,11 +3162,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool value = GET_ACC(); // fast path SAVE_ACC(); -#ifdef ECMASCRIPT_ENABLE_STUB_AOT1 +#ifdef ECMASCRIPT_ENABLE_STUB_AOT auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByName)); - typedef JSTaggedType (*PFSetPropertyByName)(uintptr_t, JSTaggedValue, JSTaggedValue, JSTaggedValue); + typedef JSTaggedType (*PFSetPropertyByName)(uintptr_t, JSTaggedType, JSTaggedType, JSTaggedType); auto setPropertyByNamePtr = reinterpret_cast(stubAddr); - JSTaggedValue res = JSTaggedValue(setPropertyByNamePtr(thread->GetGlueAddr(), receiver, propKey, value)); + JSTaggedValue res = JSTaggedValue(setPropertyByNamePtr(thread->GetGlueAddr(), + receiver.GetRawData(), propKey.GetRawData(), value.GetRawData())); #else JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value); #endif @@ -3445,7 +3453,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool void EcmaInterpreter::InitStackFrame(JSThread *thread) { uint64_t *prevSp = const_cast(thread->GetCurrentSPFrame()); - FrameState *state = GET_FRAME(prevSp); + InterpretedFrame *state = GET_FRAME(prevSp); state->pc = nullptr; state->sp = nullptr; state->function = JSTaggedValue::Hole(); @@ -3496,14 +3504,14 @@ void EcmaInterpreter::InterpreterFrameCopyArgs(JSTaggedType *newSp, uint32_t num JSTaggedValue EcmaInterpreter::GetThisFunction(JSTaggedType *sp) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp) - 1; + InterpretedFrame *state = reinterpret_cast(sp) - 1; return state->function; } JSTaggedValue EcmaInterpreter::GetNewTarget(JSTaggedType *sp) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp) - 1; + InterpretedFrame *state = reinterpret_cast(sp) - 1; JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget(); uint32_t callType = method->GetCallType(); ASSERT(callType & HAVE_NEWTARGET_BIT); @@ -3515,7 +3523,7 @@ JSTaggedValue EcmaInterpreter::GetNewTarget(JSTaggedType *sp) uint32_t EcmaInterpreter::GetNumArgs(JSTaggedType *sp, uint32_t restIdx, uint32_t &startIdx) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp) - 1; + InterpretedFrame *state = reinterpret_cast(sp) - 1; JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget(); uint32_t callType = method->GetCallType(); ASSERT(callType & HAVE_EXTRA_BIT); @@ -3569,13 +3577,13 @@ size_t EcmaInterpreter::GetJumpSizeAfterCall(const uint8_t *prevPc) JSTaggedValue EcmaInterpreter::GetRuntimeProfileTypeInfo(JSTaggedType *sp) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp) - 1; + InterpretedFrame *state = reinterpret_cast(sp) - 1; return state->profileTypeInfo; } bool EcmaInterpreter::UpdateHotnessCounter(JSThread* thread, JSTaggedType *sp, JSTaggedValue acc, int32_t offset) { - FrameState *state = GET_FRAME(sp); + InterpretedFrame *state = GET_FRAME(sp); auto method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget(); auto hotnessCounter = static_cast(method->GetHotnessCounter()); diff --git a/ecmascript/interpreter/interpreter.h b/ecmascript/interpreter/interpreter.h index d513a626bc..c13d1ae7e0 100755 --- a/ecmascript/interpreter/interpreter.h +++ b/ecmascript/interpreter/interpreter.h @@ -27,22 +27,8 @@ class ConstantPool; class ECMAObject; class GeneratorContext; -// align with 8 -// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) -struct FrameState { - const uint8_t *pc; - JSTaggedType *sp; - // aligned with 8 bits - alignas(sizeof(uint64_t)) JSTaggedValue constpool; - JSTaggedValue function; - JSTaggedValue profileTypeInfo; - JSTaggedValue acc; - JSTaggedValue env; - InterpretedFrameStateBase base; -}; - // NOLINTNEXTLINE(bugprone-sizeof-expression) -static const uint32_t FRAME_STATE_SIZE = sizeof(FrameState) / sizeof(uint64_t); +static const uint32_t FRAME_STATE_SIZE = sizeof(InterpretedFrame) / sizeof(uint64_t); static constexpr uint32_t RESERVED_CALL_ARGCOUNT = 3; static constexpr uint32_t RESERVED_INDEX_CALL_TARGET = 0; @@ -64,7 +50,7 @@ public: static inline JSTaggedValue Execute(JSThread *thread, const CallParams& params); static inline JSTaggedValue ExecuteNative(JSThread *thread, const CallParams& params); - static inline JSTaggedType *GetCurrentInterpretedFrameSp(JSThread *thread); + static inline JSTaggedType *FixSpIfNeed(JSThread *thread); static inline JSTaggedValue GeneratorReEnterInterpreter(JSThread *thread, JSHandle context); static inline void ChangeGenContext(JSThread *thread, JSHandle context); static inline void ResumeContext(JSThread *thread); diff --git a/ecmascript/js_thread.h b/ecmascript/js_thread.h index d63e2c6342..85a968b519 100644 --- a/ecmascript/js_thread.h +++ b/ecmascript/js_thread.h @@ -85,16 +85,6 @@ public: currentFrame_ = sp; } - const JSTaggedType *GetLastInterpretedFrameSp() const - { - return lastIFrame_; - } - - void SetLastIFrameSp(JSTaggedType *sp) - { - lastIFrame_ = sp; - } - bool DoStackOverflowCheck(const JSTaggedType *sp); bool IsEcmaInterpreter() const @@ -226,14 +216,6 @@ public: void IterateWeakEcmaGlobalStorage(const WeakRootVisitor &visitor); - uintptr_t* GetLastOptCallRuntimePc() const - { - return lastOptCallRuntimePc_; - } - void SetLastOptCallRuntimePc(uintptr_t* pc) - { - lastOptCallRuntimePc_ = pc; - } PropertiesCache *GetPropertiesCache() const { return propertiesCache_; @@ -347,6 +329,9 @@ public: LAST_I_FRAME, RUNTIME_FUNCTIONS, FAST_STUB_ENTRIES, + FRAME_STATE_SIZE, + OPT_LEAVE_FRAME_SIZE, + OPT_LEAVE_FRAME_PREV_OFFSET, NUMBER_OF_GLUE, }; @@ -418,15 +403,32 @@ static constexpr uint32_t GLUE_EXCEPTION_OFFSET_64 = 0U; GLUE_OFFSET_LIST(GLUE_OFFSET_MACRO) #undef GLUE_OFFSET_MACRO +static constexpr uint32_t GLUE_FRAME_STATE_SIZE_64 = + 2 * sizeof(int64_t) + 5 * sizeof(int64_t) + sizeof(int64_t) + sizeof(int64_t); +static constexpr uint32_t GLUE_OPT_LEAVE_FRAME_SIZE_64 = 5 * sizeof(uint64_t); +static constexpr uint32_t GLUE_OPT_LEAVE_FRAME_PREV_OFFSET_64 = sizeof(uint64_t); +static constexpr uint32_t GLUE_FRAME_STATE_SIZE_32 = + 2 * sizeof(int32_t) + 5 * sizeof(int64_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(int64_t); +static constexpr uint32_t GLUE_OPT_LEAVE_FRAME_SIZE_32 = sizeof(uint64_t) + 4 * sizeof(uint32_t) + sizeof(uint64_t); +static constexpr uint32_t GLUE_OPT_LEAVE_FRAME_PREV_OFFSET_32 = sizeof(uint64_t); + #ifdef PANDA_TARGET_32 #define GLUE_OFFSET_MACRO(name, camelName, lastName, lastSize32, lastSize64) \ static_assert(GLUE_##name##_OFFSET_32 == \ (JSThread::Get##camelName##Offset() - JSThread::GetExceptionOffset())); GLUE_OFFSET_LIST(GLUE_OFFSET_MACRO) #undef GLUE_OFFSET_MACRO + +static_assert(GLUE_FRAME_STATE_SIZE_32 == sizeof(struct panda::ecmascript::InterpretedFrame)); +static_assert(GLUE_OPT_LEAVE_FRAME_SIZE_32 == sizeof(struct panda::ecmascript::OptLeaveFrame)); +static_assert(GLUE_OPT_LEAVE_FRAME_PREV_OFFSET_32 == MEMBER_OFFSET(panda::ecmascript::OptLeaveFrame, prev)); #endif #ifdef PANDA_TARGET_64 + +static_assert(GLUE_FRAME_STATE_SIZE_64 == sizeof(struct panda::ecmascript::InterpretedFrame)); +static_assert(GLUE_OPT_LEAVE_FRAME_SIZE_64 == sizeof(struct panda::ecmascript::OptLeaveFrame)); +static_assert(GLUE_OPT_LEAVE_FRAME_PREV_OFFSET_64 == MEMBER_OFFSET(panda::ecmascript::OptLeaveFrame, prev)); #define GLUE_OFFSET_MACRO(name, camelName, lastName, lastSize32, lastSize64) \ static_assert(GLUE_##name##_OFFSET_64 == \ (JSThread::Get##camelName##Offset() - JSThread::GetExceptionOffset())); diff --git a/ecmascript/mem/heap.cpp b/ecmascript/mem/heap.cpp index 4fa109b393..4d6cbe21d0 100644 --- a/ecmascript/mem/heap.cpp +++ b/ecmascript/mem/heap.cpp @@ -74,9 +74,7 @@ void Heap::Initialize() semiSpaceCollector_ = new SemiSpaceCollector(this, paralledGc_); compressCollector_ = new CompressCollector(this); - derivedPointers_ = new ChunkVector(ecmaVm_->GetChunk()); - derivedPointers_->resize(STACK_MAP_DEFALUT_DERIVED_SIZE); - derivedPointers_->clear(); + derivedPointers_ = new ChunkMap(ecmaVm_->GetChunk()); mixSpaceCollector_ = new MixSpaceCollector(this); sweeper_ = new ConcurrentSweeper(this, ecmaVm_->GetJSOptions().IsEnableConcurrentSweep()); concurrentMarker_ = new ConcurrentMarker(this); @@ -376,20 +374,24 @@ void Heap::UpdateDerivedObjectInStack() return; } for (auto derived : *derivedPointers_) { - auto baseAddr = reinterpret_cast(std::get<0>(derived)); + auto baseAddr = reinterpret_cast(derived.first.first); JSTaggedValue base = *baseAddr; if (base.IsHeapObject()) { - uintptr_t baseOldObject = std::get<1>(derived); - uintptr_t *derivedAddr = reinterpret_cast(std::get<2>(derived)); + uintptr_t baseOldObject = derived.second; + uintptr_t *derivedAddr = reinterpret_cast(derived.first.second); +#ifndef NDEBUG + LOG_ECMA(DEBUG) << std::hex << "fix base before:" << baseAddr << " base old Value: " << baseOldObject << + " derived:" << derivedAddr << " old Value: " << *derivedAddr << std::endl; +#endif // derived is always bigger than base *derivedAddr = reinterpret_cast(base.GetHeapObject()) + (*derivedAddr - baseOldObject); #ifndef NDEBUG - LOG_ECMA(DEBUG) << std::hex << "fix base:" << baseAddr << " base Value: " << base.GetHeapObject() << - " derived:" << derivedAddr << " New Value: " << *derivedAddr; + LOG_ECMA(DEBUG) << std::hex << "fix base after:" << baseAddr << + " base New Value: " << base.GetHeapObject() << + " derived:" << derivedAddr << " New Value: " << *derivedAddr << std::endl; #endif } } - derivedPointers_->resize(STACK_MAP_DEFALUT_DERIVED_SIZE); derivedPointers_->clear(); } diff --git a/ecmascript/mem/heap.h b/ecmascript/mem/heap.h index d77c326d75..e37b728c31 100644 --- a/ecmascript/mem/heap.h +++ b/ecmascript/mem/heap.h @@ -41,7 +41,7 @@ class ParallelEvacuation; class EvacuationAllocator; class WorkerHelper; -using DerivedData = std::tuple; +using DerivedDataKey = std::pair; class Heap { public: @@ -294,7 +294,7 @@ public: inline void ClearSlotsRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd); - ChunkVector *GetDerivedPointers() const + ChunkMap *GetDerivedPointers() const { return derivedPointers_; } @@ -392,7 +392,7 @@ private: HeapTracker *tracker_ {nullptr}; MemController *memController_ {nullptr}; size_t oldSpaceAllocLimit_ {OLD_SPACE_LIMIT_BEGIN}; - ChunkVector *derivedPointers_ {nullptr}; + ChunkMap *derivedPointers_ {nullptr}; #if ECMASCRIPT_ENABLE_HEAP_VERIFY bool isVerifying_ {false}; #endif diff --git a/ecmascript/runtime_trampolines.cpp b/ecmascript/runtime_trampolines.cpp index 6a26d75f50..6773660409 100644 --- a/ecmascript/runtime_trampolines.cpp +++ b/ecmascript/runtime_trampolines.cpp @@ -29,16 +29,13 @@ #include "ecmascript/object_factory.h" #include "ecmascript/tagged_dictionary.h" #include "libpandabase/utils/string_helpers.h" +#include namespace panda::ecmascript { bool RuntimeTrampolines::AddElementInternal(uintptr_t argGlue, JSTaggedType argReceiver, uint32_t argIndex, JSTaggedType argValue, uint32_t argAttr) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle receiver(thread, reinterpret_cast(argReceiver)); JSHandle value(thread, JSTaggedValue(reinterpret_cast(argValue))); @@ -49,11 +46,7 @@ bool RuntimeTrampolines::AddElementInternal(uintptr_t argGlue, JSTaggedType argR bool RuntimeTrampolines::CallSetter(uintptr_t argGlue, JSTaggedType argSetter, JSTaggedType argReceiver, JSTaggedType argValue, bool argMayThrow) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle receiver(thread, JSTaggedValue(reinterpret_cast(argReceiver))); JSHandle value(thread, JSTaggedValue(reinterpret_cast(argValue))); @@ -64,11 +57,7 @@ bool RuntimeTrampolines::CallSetter(uintptr_t argGlue, JSTaggedType argSetter, J JSTaggedType RuntimeTrampolines::CallSetter2(uintptr_t argGlue, JSTaggedType argReceiver, JSTaggedType argValue, JSTaggedType argAccessor) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle objHandle(thread, JSTaggedValue(reinterpret_cast(argReceiver))); @@ -82,11 +71,7 @@ JSTaggedType RuntimeTrampolines::CallSetter2(uintptr_t argGlue, JSTaggedType arg JSTaggedType RuntimeTrampolines::CallGetter2(uintptr_t argGlue, JSTaggedType argReceiver, JSTaggedType argHolder, JSTaggedType argAccessor) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); AccessorData *accessor = AccessorData::Cast(JSTaggedValue(argAccessor).GetTaggedObject()); if (UNLIKELY(accessor->IsInternal())) { @@ -99,11 +84,7 @@ JSTaggedType RuntimeTrampolines::CallGetter2(uintptr_t argGlue, JSTaggedType arg void RuntimeTrampolines::ThrowTypeError(uintptr_t argGlue, int argMessageStringId) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); std::string message = MessageString::GetMessageString(argMessageStringId); ObjectFactory *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory(); @@ -114,11 +95,7 @@ void RuntimeTrampolines::ThrowTypeError(uintptr_t argGlue, int argMessageStringI bool RuntimeTrampolines::JSProxySetProperty(uintptr_t argGlue, JSTaggedType argProxy, JSTaggedType argKey, JSTaggedType argValue, JSTaggedType argReceiver, bool argMayThrow) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle proxy(thread, JSTaggedValue(reinterpret_cast(argProxy))); JSHandle index(thread, JSTaggedValue(reinterpret_cast(argKey))); @@ -136,11 +113,7 @@ uint32_t RuntimeTrampolines::GetHash32(uintptr_t key, uint32_t len) JSTaggedType RuntimeTrampolines::CallGetter(uintptr_t argGlue, JSTaggedType argGetter, JSTaggedType argReceiver) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto accessor = AccessorData::Cast(reinterpret_cast(argGetter)); JSHandle objHandle(thread, JSTaggedValue(reinterpret_cast(argReceiver))); @@ -150,11 +123,7 @@ JSTaggedType RuntimeTrampolines::CallGetter(uintptr_t argGlue, JSTaggedType argG JSTaggedType RuntimeTrampolines::CallInternalGetter(uintptr_t argGlue, JSTaggedType argAccessor, JSTaggedType argReceiver) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto accessor = AccessorData::Cast(reinterpret_cast(argAccessor)); JSHandle objHandle(thread, JSTaggedValue(reinterpret_cast(argReceiver))); @@ -201,11 +170,7 @@ void RuntimeTrampolines::PrintHeapReginInfo(uintptr_t argGlue) JSTaggedType RuntimeTrampolines::GetTaggedArrayPtrTest(uintptr_t argGlue) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); // this case static static JSHandle arr don't free in first call // second call trigger gc. // don't call EcmaHandleScope handleScope(thread); @@ -261,22 +226,14 @@ double RuntimeTrampolines::FloatMod(double left, double right) JSTaggedType RuntimeTrampolines::NewInternalString(uintptr_t argGlue, JSTaggedType argKey) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); JSHandle keyHandle(thread, JSTaggedValue(reinterpret_cast(argKey))); return JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(keyHandle)).GetRawData(); } JSTaggedType RuntimeTrampolines::NewTaggedArray(uintptr_t argGlue, uint32_t length) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); return factory->NewTaggedArray(length).GetTaggedValue().GetRawData(); @@ -284,11 +241,7 @@ JSTaggedType RuntimeTrampolines::NewTaggedArray(uintptr_t argGlue, uint32_t leng JSTaggedType RuntimeTrampolines::CopyArray(uintptr_t argGlue, JSTaggedType argArray, uint32_t length, uint32_t capacity) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle array(thread, JSTaggedValue(reinterpret_cast(argArray))); @@ -298,11 +251,7 @@ JSTaggedType RuntimeTrampolines::CopyArray(uintptr_t argGlue, JSTaggedType argAr JSTaggedType RuntimeTrampolines::NameDictPutIfAbsent(uintptr_t argGlue, JSTaggedType receiver, JSTaggedType array, JSTaggedType key, JSTaggedType value, uint32_t attr, bool needTransToDict) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle keyHandle(thread, JSTaggedValue(reinterpret_cast(key))); JSHandle valueHandle(thread, JSTaggedValue(reinterpret_cast(value))); @@ -323,10 +272,6 @@ void RuntimeTrampolines::PropertiesSetValue(uintptr_t argGlue, JSTaggedType argR JSTaggedType argArray, uint32_t capacity, uint32_t index) { auto thread = JSThread::GlueToJSThread(argGlue); - uintptr_t *curFp = nullptr; - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle properties; @@ -350,10 +295,6 @@ JSTaggedType RuntimeTrampolines::TaggedArraySetValue(uintptr_t argGlue, JSTagged { auto thread = JSThread::GlueToJSThread(argGlue); auto elements = reinterpret_cast(argElement); - uintptr_t *curFp = nullptr; - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); JSTaggedValue value(argValue); if (elementIndex >= capacity) { if (JSObject::ShouldTransToDict(capacity, elementIndex)) { @@ -372,31 +313,25 @@ JSTaggedType RuntimeTrampolines::TaggedArraySetValue(uintptr_t argGlue, JSTagged return JSTaggedValue::Undefined().GetRawData(); } -JSTaggedType RuntimeTrampolines::NewEcmaDynClass(uintptr_t argGlue, uint32_t size, uint8_t type) +JSTaggedType RuntimeTrampolines::NewEcmaDynClass(uintptr_t argGlue, uint32_t size, uint32_t type, uint32_t inlinedProps) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); - return (thread->GetEcmaVM()->GetFactory()->NewEcmaDynClass(size, JSType(type))).GetTaggedValue().GetRawData(); + return (thread->GetEcmaVM()->GetFactory()->NewEcmaDynClass(size, JSType(type), inlinedProps)). + GetTaggedValue().GetRawData(); } void RuntimeTrampolines::UpdateLayOutAndAddTransition(uintptr_t argGlue, JSTaggedType oldHClass, JSTaggedType newHClass, JSTaggedType key, uint32_t attr) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); auto factory = thread->GetEcmaVM()->GetFactory(); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle oldHClassHandle(thread, reinterpret_cast(oldHClass)); JSHandle newHClassHandle(thread, reinterpret_cast(newHClass)); JSHandle keyHandle(thread, JSTaggedValue(reinterpret_cast(key))); PropertyAttributes attrValue(attr); int offset = attrValue.GetOffset(); + newHClassHandle->IncNumberOfProps(); { JSMutableHandle layoutInfoHandle(thread, newHClassHandle->GetLayout()); @@ -430,11 +365,7 @@ void RuntimeTrampolines::DebugPrint(int fmtMessageId, ...) void RuntimeTrampolines::NoticeThroughChainAndRefreshUser(uintptr_t argGlue, JSTaggedType argoldHClass, JSTaggedType argnewHClass) { - uintptr_t *curFp = nullptr; auto thread = JSThread::GlueToJSThread(argGlue); - GET_CURRETN_FP(curFp); - uintptr_t *prevFp = GET_PREV_FP(curFp); - CallRuntimeTrampolinesScope scope(thread, prevFp, curFp); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle oldHClassHandle(thread, reinterpret_cast(argoldHClass)); JSHandle newHClassHandle(thread, reinterpret_cast(argnewHClass)); diff --git a/ecmascript/runtime_trampolines.h b/ecmascript/runtime_trampolines.h index 5bff285652..3a0973c960 100644 --- a/ecmascript/runtime_trampolines.h +++ b/ecmascript/runtime_trampolines.h @@ -62,7 +62,7 @@ public: JSTaggedType argValue); static double FloatMod(double left, double right); static JSTaggedType NewInternalString(uintptr_t argGlue, JSTaggedType argKey); - static JSTaggedType NewEcmaDynClass(uintptr_t argGlue, uint32_t size, uint8_t type); + static JSTaggedType NewEcmaDynClass(uintptr_t argGlue, uint32_t size, uint32_t type, uint32_t inlinedProps); static void UpdateLayOutAndAddTransition(uintptr_t argGlue, JSTaggedType oldHClass, JSTaggedType newHClass, JSTaggedType key, uint32_t attr); static void PrintHeapReginInfo(uintptr_t argGlue); @@ -77,31 +77,5 @@ public: static void DebugPrint(int fmtMessageId, ...); static void NoticeThroughChainAndRefreshUser(uintptr_t argGlue, uint64_t argoldHClass, uint64_t argnewHClass); }; - -class CallRuntimeTrampolinesScope { -public: - CallRuntimeTrampolinesScope(JSThread *thread, uintptr_t *newFp, uintptr_t *pc) - :lastFp_(nullptr), - thread_(thread) - { - lastOptCallRuntimePc_ = thread->GetLastOptCallRuntimePc(); - thread->SetLastOptCallRuntimePc(pc); - JSTaggedType *cursp = const_cast(thread->GetCurrentSPFrame()); - lastFp_ = static_cast(static_cast(cursp)); - thread->SetLastIFrameSp(cursp); - JSTaggedType *newSp = static_cast(static_cast(newFp)); - thread_->SetCurrentSPFrame(newSp); - } - ~CallRuntimeTrampolinesScope() - { - JSTaggedType *oldSp = static_cast(static_cast(lastFp_)); - thread_->SetCurrentSPFrame(oldSp); - thread_->SetLastOptCallRuntimePc(lastOptCallRuntimePc_); - } -private: - uintptr_t *lastFp_; - JSThread *thread_; - uintptr_t *lastOptCallRuntimePc_; -}; } // namespace panda::ecmascript #endif diff --git a/ecmascript/tests/test_helper.h b/ecmascript/tests/test_helper.h index d2fcb23487..7607a2b6be 100755 --- a/ecmascript/tests/test_helper.h +++ b/ecmascript/tests/test_helper.h @@ -30,7 +30,7 @@ namespace panda::test { using panda::ecmascript::EcmaHandleScope; using panda::ecmascript::EcmaRuntimeCallInfo; using panda::ecmascript::EcmaVM; -using panda::ecmascript::FrameState; +using panda::ecmascript::InterpretedFrame; using panda::ecmascript::JSTaggedType; using panda::ecmascript::JSTaggedValue; using panda::ecmascript::JSThread; @@ -66,7 +66,7 @@ public: size_t frameSize = ecmascript::FRAME_STATE_SIZE + info->GetArgsNumber() + NUM_MANDATORY_JSFUNC_ARGS; JSTaggedType *newSp = sp - frameSize; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(newSp) - 1; + InterpretedFrame *state = reinterpret_cast(newSp) - 1; state->base.frameType = static_cast(ecmascript::FrameType::INTERPRETER_FRAME); state->base.prev = sp; state->pc = nullptr; -- Gitee From c0ba3c1f4a3103da9a2f9364642c9abaf670e312 Mon Sep 17 00:00:00 2001 From: songzhengchao Date: Fri, 31 Dec 2021 16:32:32 +0800 Subject: [PATCH 2/4] review code Signed-off-by: songzhengchao Change-Id: I3fd21354d4c3080bee86351e2281183d8d42355a --- ecmascript/compiler/BUILD.gn | 5 +- .../compiler/llvm/llvm_stackmap_parser.cpp | 50 +++++++++---------- .../compiler/llvm/llvm_stackmap_parser.h | 4 +- ecmascript/compiler/tests/BUILD.gn | 5 +- ecmascript/compiler/tests/stub_tests.cpp | 2 +- ecmascript/frames.h | 8 +-- ecmascript/interpreter/interpreter-inl.h | 18 +++---- ecmascript/interpreter/interpreter.h | 2 +- 8 files changed, 50 insertions(+), 44 deletions(-) diff --git a/ecmascript/compiler/BUILD.gn b/ecmascript/compiler/BUILD.gn index 12120aedc4..3c278c4fa6 100644 --- a/ecmascript/compiler/BUILD.gn +++ b/ecmascript/compiler/BUILD.gn @@ -30,6 +30,7 @@ config("include_llvm") { include_dirs = [ "//prebuilts/ark_js_prebuilts/llvm_prebuilts/llvm/include", "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/include", + "//prebuilts/ark_js_prebuilts/llvm_prebuilts/include", ] } } @@ -63,7 +64,9 @@ source_set("libark_jsoptimizer_static") { if (compile_llvm_online) { lib_dirs = [ "//third_party/llvm-project/build/lib" ] } else { - lib_dirs = [ "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/lib" ] + lib_dirs = [ "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/lib", + "//prebuilts/ark_js_prebuilts/llvm_prebuilts/include", + ] } libs = [ diff --git a/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp b/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp index e901208246..750550d86e 100644 --- a/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp +++ b/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp @@ -63,20 +63,20 @@ const CallSiteInfo* LLVMStackMapParser::GetCallSiteInfoByPatchID(uint64_t patchP } void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, - panda::ecmascript::OptLeaveFrame *state) + OptLeaveFrame *frame) { int i = 0; uintptr_t address = 0; uintptr_t base = 0; uintptr_t derived = 0; for (auto &info: *infos) { - if (info.first == panda::ecmascript::FrameCommonConstants::SP_DWARF_REG_NUM) { - uintptr_t rsp = state->sp; + if (info.first == FrameCommonConstants::SP_DWARF_REG_NUM) { + uintptr_t rsp = frame->sp; address = rsp + info.second; LOG_ECMA(DEBUG) << std::dec << "SP_DWARF_REG_NUM: info.second:" << info.second << std::hex << "rsp :" << rsp; - } else if (info.first == panda::ecmascript::FrameCommonConstants::FP_DWARF_REG_NUM) { - uintptr_t fp = state->fp; + } else if (info.first == FrameCommonConstants::FP_DWARF_REG_NUM) { + uintptr_t fp = frame->fp; address = fp + info.second; LOG_ECMA(DEBUG) << std::dec << "FP_DWARF_REG_NUM: info.second:" << info.second << std::hex << "rfp :" << fp; @@ -102,13 +102,13 @@ void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, i = 0; } -bool LLVMStackMapParser::GetStackMapIterm(panda::ecmascript::OptLeaveFrame *state, +bool LLVMStackMapParser::GetStackMapIterm(OptLeaveFrame *frame, const RootVisitor &v0, const RootRangeVisitor &v1, - panda::ecmascript::ChunkMap *data, + ChunkMap *data, [[maybe_unused]] bool isVerifying) const { - ASSERT(state); - uint64_t patchpointId = state->patchId; + ASSERT(frame); + uint64_t patchpointId = frame->patchId; const CallSiteInfo *infos = GetCallSiteInfoByPc(patchpointId); if (infos == nullptr) { return false; @@ -118,15 +118,15 @@ bool LLVMStackMapParser::GetStackMapIterm(panda::ecmascript::OptLeaveFrame *stat uintptr_t derived = 0; int i = 0; #if ECMASCRIPT_ENABLE_COMPILER_LOG - PrintCallSiteInfo(infos, state); + PrintCallSiteInfo(infos, frame); #endif for (auto &info: *infos) { - if (info.first == panda::ecmascript::FrameCommonConstants::SP_DWARF_REG_NUM) { - uintptr_t rsp = state->sp; + if (info.first == FrameCommonConstants::SP_DWARF_REG_NUM) { + uintptr_t rsp = frame->sp; address = rsp + info.second; - } else if (info.first == panda::ecmascript::FrameCommonConstants::FP_DWARF_REG_NUM) { - uintptr_t fp = state->fp; + } else if (info.first == FrameCommonConstants::FP_DWARF_REG_NUM) { + uintptr_t fp = frame->fp; address = fp + info.second; } else { abort(); @@ -134,7 +134,7 @@ bool LLVMStackMapParser::GetStackMapIterm(panda::ecmascript::OptLeaveFrame *stat if (IsDeriveredPointer(i)) { derived = reinterpret_cast(address); if (base == derived) { - v0(panda::ecmascript::Root::ROOT_FRAME, panda::ecmascript::ObjectSlot(base)); + v0(Root::ROOT_FRAME, ObjectSlot(base)); } else { #if ECMASCRIPT_ENABLE_HEAP_VERIFY if (!isVerifying) { @@ -160,17 +160,17 @@ void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, uintptr_t base = 0; uintptr_t derived = 0; for (auto &info: *infos) { - if (info.first == panda::ecmascript::FrameCommonConstants::SP_DWARF_REG_NUM) { + if (info.first == FrameCommonConstants::SP_DWARF_REG_NUM) { #ifdef PANDA_TARGET_ARM64 uintptr_t *curFp = reinterpret_cast(*fp); - uintptr_t *rsp = reinterpret_cast(*(curFp + panda::ecmascript::FrameCommonConstants::SP_OFFSET)); + uintptr_t *rsp = reinterpret_cast(*(curFp + FrameCommonConstants::SP_OFFSET)); #else - uintptr_t *rsp = fp + panda::ecmascript::FrameCommonConstants::SP_OFFSET; + uintptr_t *rsp = fp + FrameCommonConstants::SP_OFFSET; #endif address = reinterpret_cast(rsp) + info.second; LOG_ECMA(DEBUG) << "SP_DWARF_REG_NUM: info.second:" << info.second << " rbp offset:" << reinterpret_cast(*fp) - address << "rsp :" << rsp; - } else if (info.first == panda::ecmascript::FrameCommonConstants::FP_DWARF_REG_NUM) { + } else if (info.first == FrameCommonConstants::FP_DWARF_REG_NUM) { uintptr_t tmpFp = *fp; address = tmpFp + info.second; LOG_ECMA(DEBUG) << "FP_DWARF_REG_NUM: info.second:" << info.second; @@ -202,7 +202,7 @@ bool LLVMStackMapParser::IsDeriveredPointer(int callsitetime) const bool LLVMStackMapParser::GetStackMapIterm(uintptr_t callSiteAddr, uintptr_t frameFp, const RootVisitor &v0, const RootRangeVisitor &v1, - panda::ecmascript::ChunkMap *data, + ChunkMap *data, [[maybe_unused]] bool isVerifying) const { const CallSiteInfo *infos = GetCallSiteInfoByPc(callSiteAddr); @@ -218,15 +218,15 @@ bool LLVMStackMapParser::GetStackMapIterm(uintptr_t callSiteAddr, uintptr_t fram PrintCallSiteInfo(infos, fp); #endif for (auto &info: *infos) { - if (info.first == panda::ecmascript::FrameCommonConstants::SP_DWARF_REG_NUM) { + if (info.first == FrameCommonConstants::SP_DWARF_REG_NUM) { #ifdef PANDA_TARGET_ARM64 uintptr_t *curFp = reinterpret_cast(*fp); - uintptr_t *rsp = reinterpret_cast(*(curFp + panda::ecmascript::FrameCommonConstants::SP_OFFSET)); + uintptr_t *rsp = reinterpret_cast(*(curFp + FrameCommonConstants::SP_OFFSET)); #else - uintptr_t *rsp = fp + panda::ecmascript::FrameCommonConstants::SP_OFFSET; + uintptr_t *rsp = fp + FrameCommonConstants::SP_OFFSET; #endif address = reinterpret_cast(rsp) + info.second; - } else if (info.first == panda::ecmascript::FrameCommonConstants::FP_DWARF_REG_NUM) { + } else if (info.first == FrameCommonConstants::FP_DWARF_REG_NUM) { uintptr_t tmpFp = *fp; address = tmpFp + info.second; } else { @@ -236,7 +236,7 @@ bool LLVMStackMapParser::GetStackMapIterm(uintptr_t callSiteAddr, uintptr_t fram if (IsDeriveredPointer(i)) { derived = reinterpret_cast(address); if (base == derived) { - v0(panda::ecmascript::Root::ROOT_FRAME, panda::ecmascript::ObjectSlot(base)); + v0(Root::ROOT_FRAME, ObjectSlot(base)); } else { #if ECMASCRIPT_ENABLE_HEAP_VERIFY if (!isVerifying) { diff --git a/ecmascript/compiler/llvm/llvm_stackmap_parser.h b/ecmascript/compiler/llvm/llvm_stackmap_parser.h index 23f0539457..c9d4c99556 100644 --- a/ecmascript/compiler/llvm/llvm_stackmap_parser.h +++ b/ecmascript/compiler/llvm/llvm_stackmap_parser.h @@ -205,7 +205,7 @@ public: bool GetStackMapIterm(uintptr_t callSiteAddr, uintptr_t frameFp, const RootVisitor &v0, const RootRangeVisitor &v1, panda::ecmascript::ChunkMap *data, [[maybe_unused]] bool isVerifying) const; - bool GetStackMapIterm(panda::ecmascript::OptLeaveFrame *state, + bool GetStackMapIterm(panda::ecmascript::OptLeaveFrame *frame, const RootVisitor &v0, const RootRangeVisitor &v1, panda::ecmascript::ChunkMap *data, [[maybe_unused]] bool isVerifying) const; @@ -230,7 +230,7 @@ private: void CalcCallSite(); bool IsDeriveredPointer(int callsitetime) const; const CallSiteInfo* GetCallSiteInfoByPatchID(uint64_t patchPointId) const; - void PrintCallSiteInfo(const CallSiteInfo *infos, panda::ecmascript::OptLeaveFrame *state); + void PrintCallSiteInfo(const CallSiteInfo *infos, panda::ecmascript::OptLeaveFrame *frame); void PrintCallSiteInfo(const CallSiteInfo *infos, uintptr_t *fp); std::unique_ptr stackMapAddr_; struct LLVMStackMap llvmStackMap_; diff --git a/ecmascript/compiler/tests/BUILD.gn b/ecmascript/compiler/tests/BUILD.gn index 5268dae914..4eda25721a 100644 --- a/ecmascript/compiler/tests/BUILD.gn +++ b/ecmascript/compiler/tests/BUILD.gn @@ -25,6 +25,7 @@ config("include_llvm_config") { include_dirs = [ "//prebuilts/ark_js_prebuilts/llvm_prebuilts/llvm/include", "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/include", + "//prebuilts/ark_js_prebuilts/llvm_prebuilts/include", ] } } @@ -49,7 +50,9 @@ host_unittest_action("StubTest") { if (compile_llvm_online) { lib_dirs = [ "//third_party/llvm-project/build/lib" ] } else { - lib_dirs = [ "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/lib" ] + lib_dirs = [ "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/lib", + "//prebuilts/ark_js_prebuilts/llvm_prebuilts/include", + ] } libs = [ diff --git a/ecmascript/compiler/tests/stub_tests.cpp b/ecmascript/compiler/tests/stub_tests.cpp index 5f718a1a96..da1e8091ec 100644 --- a/ecmascript/compiler/tests/stub_tests.cpp +++ b/ecmascript/compiler/tests/stub_tests.cpp @@ -888,7 +888,7 @@ void DoSafepoint() uintptr_t returnAddr = *(rbp + 1); uintptr_t *rsp = rbp + 2; // move 2 steps from rbp to get rsp rbp = reinterpret_cast(*rbp); - const ::kungfu::DwarfRegAndOffsetTypeVector *infos = + const ::kungfu::CallSiteInfo *infos = ::kungfu::LLVMStackMapParser::GetInstance().GetCallSiteInfoByPc(returnAddr); if (infos != nullptr) { for (auto &info : *infos) { diff --git a/ecmascript/frames.h b/ecmascript/frames.h index b8a5a7283b..c50ed7a418 100755 --- a/ecmascript/frames.h +++ b/ecmascript/frames.h @@ -147,7 +147,7 @@ public: ~OptimizedFrame() = default; uint64_t frameType; JSTaggedType *prev; // for llvm :c-fp ; for interrupt: thread-fp for gc - static OptimizedFrame * GetFrameFromSp(panda::ecmascript::JSTaggedType *sp) + static OptimizedFrame * GetFrameFromSp(JSTaggedType *sp) { return reinterpret_cast(reinterpret_cast(sp) - MEMBER_OFFSET(OptimizedFrame, prev)); @@ -168,7 +168,7 @@ public: ~OptimizedEntryFrame() = default; JSTaggedType *threadFp; // for gc OptimizedFrame base; - static OptimizedEntryFrame* GetFrameFromSp(panda::ecmascript::JSTaggedType *sp) + static OptimizedEntryFrame* GetFrameFromSp(JSTaggedType *sp) { return reinterpret_cast(reinterpret_cast(sp) - MEMBER_OFFSET(OptimizedEntryFrame, base.prev)); @@ -187,7 +187,7 @@ struct InterpretedFrame { JSTaggedValue acc; JSTaggedValue env; InterpretedFrameBase base; - static InterpretedFrame * GetFrameFromSp(panda::ecmascript::JSTaggedType *sp) + static InterpretedFrame * GetFrameFromSp(JSTaggedType *sp) { return reinterpret_cast(sp) - 1; } @@ -199,7 +199,7 @@ struct OptLeaveFrame { uintptr_t sp; uintptr_t fp; uint64_t patchId; - static OptLeaveFrame* GetFrameFromSp(panda::ecmascript::JSTaggedType *sp) + static OptLeaveFrame* GetFrameFromSp(JSTaggedType *sp) { return reinterpret_cast(reinterpret_cast(sp) - MEMBER_OFFSET(OptLeaveFrame, prev)); diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index 64dc9ec9f7..26ba1b82cd 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -207,7 +207,7 @@ namespace panda::ecmascript { #define GET_ACC() (acc) // NOLINT(cppcoreguidelines-macro-usage) #define SET_ACC(val) (acc = val); // NOLINT(cppcoreguidelines-macro-usage) -JSTaggedType * EcmaInterpreter::FixSpIfNeed(JSThread *thread) +JSTaggedType * EcmaInterpreter::FixSpOnEntry(JSThread *thread) { JSTaggedType *current = const_cast(thread->GetCurrentSPFrame()); FrameType type = *(reinterpret_cast( @@ -225,8 +225,8 @@ JSTaggedType * EcmaInterpreter::FixSpIfNeed(JSThread *thread) JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& params) { INTERPRETER_TRACE(thread, ExecuteNative); - JSTaggedType *originalPrevSp = const_cast(thread->GetCurrentSPFrame()); - JSTaggedType *fixedSp = FixSpIfNeed(thread); + JSTaggedType *sp = const_cast(thread->GetCurrentSPFrame()); + JSTaggedType *fixedSp = FixSpOnEntry(thread); JSMethod *methodToCall = params.callTarget->GetCallTarget(); ASSERT(methodToCall->GetNumVregs() == 0); @@ -249,7 +249,7 @@ JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& } InterpretedFrame *state = GET_FRAME(newSp); - state->base.prev = originalPrevSp; + state->base.prev = sp; state->base.frameType = static_cast(FrameType::INTERPRETER_FRAME); state->pc = nullptr; state->sp = newSp; @@ -263,7 +263,7 @@ JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& JSTaggedValue tagged = reinterpret_cast(const_cast(methodToCall->GetNativePointer()))(&ecmaRuntimeCallInfo); LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call."; - thread->SetCurrentSPFrame(originalPrevSp); + thread->SetCurrentSPFrame(sp); #if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER CpuProfiler::IsNeedAndGetStack(thread); #endif @@ -278,8 +278,8 @@ JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& param if (method->IsNative()) { return EcmaInterpreter::ExecuteNative(thread, params); } - JSTaggedType *originalPrevSp = const_cast(thread->GetCurrentSPFrame()); - JSTaggedType *fixedSp = FixSpIfNeed(thread); + JSTaggedType *sp = const_cast(thread->GetCurrentSPFrame()); + JSTaggedType *fixedSp = FixSpOnEntry(thread); JSTaggedType *newSp = fixedSp - FRAME_STATE_SIZE; // push break state // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -290,7 +290,7 @@ JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& param breakState->pc = nullptr; breakState->sp = nullptr; breakState->function = JSTaggedValue::Hole(); - breakState->base.prev = originalPrevSp; + breakState->base.prev = sp; breakState->base.frameType = static_cast(FrameType::INTERPRETER_FRAME); JSTaggedType *prevSp = newSp; @@ -385,7 +385,7 @@ JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& param // NOLINTNEXTLINE(readability-identifier-naming) const JSTaggedValue resAcc = state->acc; // pop frame - thread->SetCurrentSPFrame(originalPrevSp); + thread->SetCurrentSPFrame(sp); #if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER CpuProfiler::IsNeedAndGetStack(thread); #endif diff --git a/ecmascript/interpreter/interpreter.h b/ecmascript/interpreter/interpreter.h index c13d1ae7e0..9c9281297e 100755 --- a/ecmascript/interpreter/interpreter.h +++ b/ecmascript/interpreter/interpreter.h @@ -50,7 +50,7 @@ public: static inline JSTaggedValue Execute(JSThread *thread, const CallParams& params); static inline JSTaggedValue ExecuteNative(JSThread *thread, const CallParams& params); - static inline JSTaggedType *FixSpIfNeed(JSThread *thread); + static inline JSTaggedType *FixSpOnEntry(JSThread *thread); static inline JSTaggedValue GeneratorReEnterInterpreter(JSThread *thread, JSHandle context); static inline void ChangeGenContext(JSThread *thread, JSHandle context); static inline void ResumeContext(JSThread *thread); -- Gitee From 45c5cd88666a2d4d97b22b9c1ce4fd93a4f54452 Mon Sep 17 00:00:00 2001 From: songzhengchao Date: Fri, 31 Dec 2021 22:41:51 +0800 Subject: [PATCH 3/4] codedex clean Change-Id: I439a70ae2fa6fcf6bb57bf37763cf4068abadd9a Signed-off-by: songzhengchao --- ecmascript/compiler/BUILD.gn | 5 +++-- .../compiler/llvm/llvm_stackmap_parser.cpp | 17 ++++++++--------- ecmascript/compiler/llvm_ir_builder.cpp | 4 +--- ecmascript/frames.h | 4 ++-- ecmascript/interpreter/frame_handler.cpp | 4 ++-- ecmascript/interpreter/frame_handler.h | 4 ++-- ecmascript/interpreter/interpreter-inl.h | 2 +- ecmascript/runtime_trampolines.cpp | 1 - 8 files changed, 19 insertions(+), 22 deletions(-) diff --git a/ecmascript/compiler/BUILD.gn b/ecmascript/compiler/BUILD.gn index 3c278c4fa6..6f43046fc7 100644 --- a/ecmascript/compiler/BUILD.gn +++ b/ecmascript/compiler/BUILD.gn @@ -64,8 +64,9 @@ source_set("libark_jsoptimizer_static") { if (compile_llvm_online) { lib_dirs = [ "//third_party/llvm-project/build/lib" ] } else { - lib_dirs = [ "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/lib", - "//prebuilts/ark_js_prebuilts/llvm_prebuilts/include", + lib_dirs = [ + "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/lib", + "//prebuilts/ark_js_prebuilts/llvm_prebuilts/include", ] } diff --git a/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp b/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp index 750550d86e..92d9310da7 100644 --- a/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp +++ b/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp @@ -88,10 +88,10 @@ void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, if (IsDeriveredPointer(i)) { derived = reinterpret_cast(address); if (base == derived) { - LOG_ECMA(INFO) << std::hex << "visit base:" << base << " base Value: " << + LOG_ECMA(INFO) << std::hex << "visit base:" << base << " base Value: " << *reinterpret_cast(base); } else { - LOG_ECMA(INFO) << std::hex << "push base:" << base << " base Value: " << + LOG_ECMA(INFO) << std::hex << "push base:" << base << " base Value: " << *reinterpret_cast(base) << " derived:" << derived; } } else { @@ -103,9 +103,9 @@ void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, } bool LLVMStackMapParser::GetStackMapIterm(OptLeaveFrame *frame, - const RootVisitor &v0, const RootRangeVisitor &v1, - ChunkMap *data, - [[maybe_unused]] bool isVerifying) const + const RootVisitor &v0, const RootRangeVisitor &v1, + ChunkMap *data, + [[maybe_unused]] bool isVerifying) const { ASSERT(frame); uint64_t patchpointId = frame->patchId; @@ -201,9 +201,9 @@ bool LLVMStackMapParser::IsDeriveredPointer(int callsitetime) const } bool LLVMStackMapParser::GetStackMapIterm(uintptr_t callSiteAddr, uintptr_t frameFp, - const RootVisitor &v0, const RootRangeVisitor &v1, - ChunkMap *data, - [[maybe_unused]] bool isVerifying) const + const RootVisitor &v0, const RootRangeVisitor &v1, + ChunkMap *data, + [[maybe_unused]] bool isVerifying) const { const CallSiteInfo *infos = GetCallSiteInfoByPc(callSiteAddr); if (infos == nullptr) { @@ -285,7 +285,6 @@ void LLVMStackMapParser::CalcCallSite() } else { it2->second.emplace_back(info); } - } } }; diff --git a/ecmascript/compiler/llvm_ir_builder.cpp b/ecmascript/compiler/llvm_ir_builder.cpp index 1f231769d9..ec2f0f22c4 100644 --- a/ecmascript/compiler/llvm_ir_builder.cpp +++ b/ecmascript/compiler/llvm_ir_builder.cpp @@ -594,7 +594,7 @@ void LLVMIRBuilder::ConstructFrame() interpretedFrameSize_, 1), ""); PushFrameContext(newSp, currentSp); LLVMValueRef preAddr = LLVMBuildAdd(builder_, newSp, LLVMConstInt(slotType_, - optLeaveFramePrevOffset_, 1), "");// newSp sub type size get presize + optLeaveFramePrevOffset_, 1), ""); // newSp sub type size get presize SetCurrentSPFrame(preAddr); } @@ -624,8 +624,6 @@ void LLVMIRBuilder::VisitCall(GateRef gate, const std::vector &inList) LLVMTypeRef rtfuncTypePtr = LLVMPointerType(rtfuncType, 0); LLVMValueRef glue = gateToLLVMMaps_[inList[2]]; // 2 : 2 means skip two input gates (target glue) LLVMTypeRef glue_type = LLVMTypeOf(glue); - - // runtime case if (callee_descriptor->GetStubKind() == StubDescriptor::CallStubKind::RUNTIME_STUB) { rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::RUNTIME_FUNCTIONS) + diff --git a/ecmascript/frames.h b/ecmascript/frames.h index c50ed7a418..a7e4676135 100755 --- a/ecmascript/frames.h +++ b/ecmascript/frames.h @@ -147,7 +147,7 @@ public: ~OptimizedFrame() = default; uint64_t frameType; JSTaggedType *prev; // for llvm :c-fp ; for interrupt: thread-fp for gc - static OptimizedFrame * GetFrameFromSp(JSTaggedType *sp) + static OptimizedFrame* GetFrameFromSp(JSTaggedType *sp) { return reinterpret_cast(reinterpret_cast(sp) - MEMBER_OFFSET(OptimizedFrame, prev)); @@ -187,7 +187,7 @@ struct InterpretedFrame { JSTaggedValue acc; JSTaggedValue env; InterpretedFrameBase base; - static InterpretedFrame * GetFrameFromSp(JSTaggedType *sp) + static InterpretedFrame* GetFrameFromSp(JSTaggedType *sp) { return reinterpret_cast(sp) - 1; } diff --git a/ecmascript/interpreter/frame_handler.cpp b/ecmascript/interpreter/frame_handler.cpp index 66774a9851..15784997b6 100755 --- a/ecmascript/interpreter/frame_handler.cpp +++ b/ecmascript/interpreter/frame_handler.cpp @@ -247,7 +247,7 @@ void OptimizedFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisito } void OptimizedEntryFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1, - ChunkMap *derivedPointers, bool isVerifying) const + ChunkMap *derivedPointers, bool isVerifying) const { if (sp_ != nullptr) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -278,7 +278,7 @@ void OptimizedLeaveFrameHandler::PrevFrame() } void OptimizedLeaveFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1, - ChunkMap *derivedPointers, bool isVerifying) const + ChunkMap *derivedPointers, bool isVerifying) const { OptLeaveFrame *state = reinterpret_cast( reinterpret_cast(sp_) - MEMBER_OFFSET(OptLeaveFrame, prev)); diff --git a/ecmascript/interpreter/frame_handler.h b/ecmascript/interpreter/frame_handler.h index eebf1d869a..08cdcc5aa2 100644 --- a/ecmascript/interpreter/frame_handler.h +++ b/ecmascript/interpreter/frame_handler.h @@ -56,13 +56,13 @@ public: reinterpret_cast(sp_) + FrameCommonConstants::FRAME_TYPE_OFFSET)); return type; } +protected: + JSTaggedType *sp_ {nullptr}; private: friend class InterpretedFrameHandler; friend class OptimizedFrameHandler; friend class OptimizedEntryFrameHandler; friend class OptimizedLeaveFrameHandler; -protected: - JSTaggedType *sp_ {nullptr}; }; class InterpretedFrameHandler : public FrameHandler { diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index 26ba1b82cd..267968e3c0 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -207,7 +207,7 @@ namespace panda::ecmascript { #define GET_ACC() (acc) // NOLINT(cppcoreguidelines-macro-usage) #define SET_ACC(val) (acc = val); // NOLINT(cppcoreguidelines-macro-usage) -JSTaggedType * EcmaInterpreter::FixSpOnEntry(JSThread *thread) +JSTaggedType* EcmaInterpreter::FixSpOnEntry(JSThread *thread) { JSTaggedType *current = const_cast(thread->GetCurrentSPFrame()); FrameType type = *(reinterpret_cast( diff --git a/ecmascript/runtime_trampolines.cpp b/ecmascript/runtime_trampolines.cpp index 6773660409..f54fc37648 100644 --- a/ecmascript/runtime_trampolines.cpp +++ b/ecmascript/runtime_trampolines.cpp @@ -29,7 +29,6 @@ #include "ecmascript/object_factory.h" #include "ecmascript/tagged_dictionary.h" #include "libpandabase/utils/string_helpers.h" -#include namespace panda::ecmascript { bool RuntimeTrampolines::AddElementInternal(uintptr_t argGlue, JSTaggedType argReceiver, uint32_t argIndex, -- Gitee From b92aa940ed9ea90a32f15e73e38224cabcace875 Mon Sep 17 00:00:00 2001 From: songzhengchao Date: Sat, 1 Jan 2022 11:09:01 +0800 Subject: [PATCH 4/4] code review: function rename and namespace Change-Id: I40e81947ba3b51bb5e2dc1103a985889ca78dada Signed-off-by: songzhengchao --- ecmascript/compiler/fast_stub.cpp | 2 +- .../compiler/llvm/llvm_stackmap_parser.cpp | 20 +++++++++---------- .../compiler/llvm/llvm_stackmap_parser.h | 17 +++++++--------- ecmascript/compiler/llvm_codegen.cpp | 2 +- ecmascript/compiler/llvm_ir_builder.cpp | 2 +- ecmascript/compiler/stub_descriptor.cpp | 2 +- ecmascript/compiler/tests/BUILD.gn | 7 ++++--- ecmascript/compiler/tests/stub_tests.cpp | 4 ++-- ecmascript/interpreter/frame_handler.cpp | 6 +++--- ecmascript/js_thread.cpp | 2 +- ecmascript/stub_module.cpp | 2 +- 11 files changed, 32 insertions(+), 34 deletions(-) diff --git a/ecmascript/compiler/fast_stub.cpp b/ecmascript/compiler/fast_stub.cpp index 63624f497c..515bc34fcc 100644 --- a/ecmascript/compiler/fast_stub.cpp +++ b/ecmascript/compiler/fast_stub.cpp @@ -1239,4 +1239,4 @@ void TryStoreICByValueStub::GenerateCircuit(const CompilationConfig *cfg) Bind(&receiverNotHeapObject); Return(GetHoleConstant(MachineType::UINT64)); } -} // namespace kungfu +} // namespace panda::ecmascript::kungfu diff --git a/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp b/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp index 92d9310da7..39fb6902e9 100644 --- a/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp +++ b/ecmascript/compiler/llvm/llvm_stackmap_parser.cpp @@ -25,7 +25,7 @@ using namespace panda::ecmascript; -namespace kungfu { +namespace panda::ecmascript::kungfu { std::string LocationTy::TypeToString(Kind loc) const { switch (loc) { @@ -102,10 +102,10 @@ void LLVMStackMapParser::PrintCallSiteInfo(const CallSiteInfo *infos, i = 0; } -bool LLVMStackMapParser::GetStackMapIterm(OptLeaveFrame *frame, - const RootVisitor &v0, const RootRangeVisitor &v1, - ChunkMap *data, - [[maybe_unused]] bool isVerifying) const +bool LLVMStackMapParser::VisitStackMapSlots(OptLeaveFrame *frame, + const RootVisitor &v0, const RootRangeVisitor &v1, + ChunkMap *data, + [[maybe_unused]] bool isVerifying) const { ASSERT(frame); uint64_t patchpointId = frame->patchId; @@ -200,10 +200,10 @@ bool LLVMStackMapParser::IsDeriveredPointer(int callsitetime) const return callsitetime & 1; } -bool LLVMStackMapParser::GetStackMapIterm(uintptr_t callSiteAddr, uintptr_t frameFp, - const RootVisitor &v0, const RootRangeVisitor &v1, - ChunkMap *data, - [[maybe_unused]] bool isVerifying) const +bool LLVMStackMapParser::VisitStackMapSlots(uintptr_t callSiteAddr, uintptr_t frameFp, + const RootVisitor &v0, const RootRangeVisitor &v1, + ChunkMap *data, + [[maybe_unused]] bool isVerifying) const { const CallSiteInfo *infos = GetCallSiteInfoByPc(callSiteAddr); if (infos == nullptr) { @@ -372,4 +372,4 @@ bool LLVMStackMapParser::CalculateStackMap(std::unique_ptr stackMapA CalcCallSite(); return true; } -} // namespace kungfu +} // namespace panda::ecmascript::kungfu diff --git a/ecmascript/compiler/llvm/llvm_stackmap_parser.h b/ecmascript/compiler/llvm/llvm_stackmap_parser.h index c9d4c99556..c4f5afc464 100644 --- a/ecmascript/compiler/llvm/llvm_stackmap_parser.h +++ b/ecmascript/compiler/llvm/llvm_stackmap_parser.h @@ -25,15 +25,12 @@ #include "ecmascript/ecma_macros.h" #include "ecmascript/interpreter/interpreter-inl.h" -namespace kungfu { +namespace panda::ecmascript::kungfu { using OffsetType = int32_t; using DwarfRegType = uint16_t; using DwarfRegAndOffsetType = std::pair; using CallSiteInfo = std::vector; using Fun2InfoType = std::pair; -using DerivedDataKey = panda::ecmascript::DerivedDataKey; -using RootVisitor = panda::ecmascript::RootVisitor; -using RootRangeVisitor = panda::ecmascript::RootRangeVisitor; struct Header { uint8_t stackmapversion; // Stack Map Version (current version is 3) @@ -202,12 +199,12 @@ public: llvmStackMap_.Print(); } const CallSiteInfo *GetCallSiteInfoByPc(uintptr_t funcAddr) const; - bool GetStackMapIterm(uintptr_t callSiteAddr, uintptr_t frameFp, const RootVisitor &v0, - const RootRangeVisitor &v1, panda::ecmascript::ChunkMap *data, + bool VisitStackMapSlots(uintptr_t callSiteAddr, uintptr_t frameFp, const RootVisitor &v0, + const RootRangeVisitor &v1, ChunkMap *data, [[maybe_unused]] bool isVerifying) const; - bool GetStackMapIterm(panda::ecmascript::OptLeaveFrame *frame, + bool VisitStackMapSlots(OptLeaveFrame *frame, const RootVisitor &v0, const RootRangeVisitor &v1, - panda::ecmascript::ChunkMap *data, + ChunkMap *data, [[maybe_unused]] bool isVerifying) const; private: @@ -230,7 +227,7 @@ private: void CalcCallSite(); bool IsDeriveredPointer(int callsitetime) const; const CallSiteInfo* GetCallSiteInfoByPatchID(uint64_t patchPointId) const; - void PrintCallSiteInfo(const CallSiteInfo *infos, panda::ecmascript::OptLeaveFrame *frame); + void PrintCallSiteInfo(const CallSiteInfo *infos, OptLeaveFrame *frame); void PrintCallSiteInfo(const CallSiteInfo *infos, uintptr_t *fp); std::unique_ptr stackMapAddr_; struct LLVMStackMap llvmStackMap_; @@ -238,5 +235,5 @@ private: std::unordered_map pid2CallSiteInfo_; [[maybe_unused]] std::unique_ptr dataInfo_; }; -} // namespace kungfu +} // namespace panda::ecmascript::kungfu #endif // ECMASCRIPT_COMPILER_LLVM_LLVMSTACKPARSE_H \ No newline at end of file diff --git a/ecmascript/compiler/llvm_codegen.cpp b/ecmascript/compiler/llvm_codegen.cpp index 3a877a913c..ae958917f7 100644 --- a/ecmascript/compiler/llvm_codegen.cpp +++ b/ecmascript/compiler/llvm_codegen.cpp @@ -350,4 +350,4 @@ void LLVMAssembler::Disassemble(std::map addr2name) const LLVMDisasmDispose(dcr); #endif } -} // panda::ecmascript::kungfu +} // namespace panda::ecmascript::kungfu diff --git a/ecmascript/compiler/llvm_ir_builder.cpp b/ecmascript/compiler/llvm_ir_builder.cpp index ec2f0f22c4..adedefdf98 100644 --- a/ecmascript/compiler/llvm_ir_builder.cpp +++ b/ecmascript/compiler/llvm_ir_builder.cpp @@ -1727,4 +1727,4 @@ LLVMTypeRef LLVMStubModule::ConvertLLVMTypeFromMachineType(MachineType type) } return machineTypeMap[type]; } -} // namespace kungfu +} // namespace panda::ecmascript::kungfu diff --git a/ecmascript/compiler/stub_descriptor.cpp b/ecmascript/compiler/stub_descriptor.cpp index a8bf2fae77..a1e6828bc6 100644 --- a/ecmascript/compiler/stub_descriptor.cpp +++ b/ecmascript/compiler/stub_descriptor.cpp @@ -731,4 +731,4 @@ void FastStubDescriptors::InitializeStubDescriptors() #undef INITIALIZE_CALL_STUB_DESCRIPTOR #undef DEF_CALL_STUB } -} // namespace kungfu +} // namespace panda::ecmascript::kungfu diff --git a/ecmascript/compiler/tests/BUILD.gn b/ecmascript/compiler/tests/BUILD.gn index 4eda25721a..dd69000b43 100644 --- a/ecmascript/compiler/tests/BUILD.gn +++ b/ecmascript/compiler/tests/BUILD.gn @@ -50,9 +50,10 @@ host_unittest_action("StubTest") { if (compile_llvm_online) { lib_dirs = [ "//third_party/llvm-project/build/lib" ] } else { - lib_dirs = [ "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/lib", - "//prebuilts/ark_js_prebuilts/llvm_prebuilts/include", - ] + lib_dirs = [ + "//prebuilts/ark_js_prebuilts/llvm_prebuilts/build/lib", + "//prebuilts/ark_js_prebuilts/llvm_prebuilts/include", + ] } libs = [ diff --git a/ecmascript/compiler/tests/stub_tests.cpp b/ecmascript/compiler/tests/stub_tests.cpp index da1e8091ec..f3ce856e22 100644 --- a/ecmascript/compiler/tests/stub_tests.cpp +++ b/ecmascript/compiler/tests/stub_tests.cpp @@ -888,8 +888,8 @@ void DoSafepoint() uintptr_t returnAddr = *(rbp + 1); uintptr_t *rsp = rbp + 2; // move 2 steps from rbp to get rsp rbp = reinterpret_cast(*rbp); - const ::kungfu::CallSiteInfo *infos = - ::kungfu::LLVMStackMapParser::GetInstance().GetCallSiteInfoByPc(returnAddr); + const kungfu::CallSiteInfo *infos = + kungfu::LLVMStackMapParser::GetInstance().GetCallSiteInfoByPc(returnAddr); if (infos != nullptr) { for (auto &info : *infos) { uintptr_t **address = nullptr; diff --git a/ecmascript/interpreter/frame_handler.cpp b/ecmascript/interpreter/frame_handler.cpp index 15784997b6..e62f77c8d0 100755 --- a/ecmascript/interpreter/frame_handler.cpp +++ b/ecmascript/interpreter/frame_handler.cpp @@ -235,7 +235,7 @@ void OptimizedFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisito // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) std::set slotAddrs; auto returnAddr = reinterpret_cast(*(reinterpret_cast(sp_) + 1)); - bool ret = ::kungfu::LLVMStackMapParser::GetInstance().GetStackMapIterm( + bool ret = kungfu::LLVMStackMapParser::GetInstance().VisitStackMapSlots( returnAddr, reinterpret_cast(sp_), v0, v1, derivedPointers, isVerifying); if (ret == false) { #ifndef NDEBUG @@ -253,7 +253,7 @@ void OptimizedEntryFrameHandler::Iterate(const RootVisitor &v0, const RootRangeV // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) std::set slotAddrs; auto returnAddr = reinterpret_cast(*(reinterpret_cast(sp_) + 1)); - bool ret = ::kungfu::LLVMStackMapParser::GetInstance().GetStackMapIterm( + bool ret = kungfu::LLVMStackMapParser::GetInstance().VisitStackMapSlots( returnAddr, reinterpret_cast(sp_), v0, v1, derivedPointers, isVerifying); if (ret == false) { #ifndef NDEBUG @@ -282,7 +282,7 @@ void OptimizedLeaveFrameHandler::Iterate(const RootVisitor &v0, const RootRangeV { OptLeaveFrame *state = reinterpret_cast( reinterpret_cast(sp_) - MEMBER_OFFSET(OptLeaveFrame, prev)); - bool ret = ::kungfu::LLVMStackMapParser::GetInstance().GetStackMapIterm( + bool ret = kungfu::LLVMStackMapParser::GetInstance().VisitStackMapSlots( state, v0, v1, derivedPointers, isVerifying); if (ret == false) { #ifndef NDEBUG diff --git a/ecmascript/js_thread.cpp b/ecmascript/js_thread.cpp index 9a74156daa..c5de54c31d 100644 --- a/ecmascript/js_thread.cpp +++ b/ecmascript/js_thread.cpp @@ -229,7 +229,7 @@ void JSThread::LoadFastStubModule(const char *moduleFile) fastStubEntries_[i] = stubModule.GetStubEntry(i); } #ifdef NDEBUG - ::kungfu::LLVMStackMapParser::GetInstance().Print(); + kungfu::LLVMStackMapParser::GetInstance().Print(); #endif stubCode_ = stubModule.GetCode(); } diff --git a/ecmascript/stub_module.cpp b/ecmascript/stub_module.cpp index 8f0c97e88f..4410018aeb 100644 --- a/ecmascript/stub_module.cpp +++ b/ecmascript/stub_module.cpp @@ -74,7 +74,7 @@ void StubModule::Load(JSThread *thread, const std::string &filename) std::unique_ptr stackmapPtr(std::make_unique(stackmapSize)); modulefile.read(reinterpret_cast(stackmapPtr.get()), stackmapSize); if (stackmapSize != 0) { - ::kungfu::LLVMStackMapParser::GetInstance().CalculateStackMap(std::move(stackmapPtr), + kungfu::LLVMStackMapParser::GetInstance().CalculateStackMap(std::move(stackmapPtr), hostCodeSectionAddr_, devicesCodeSectionAddr_); } modulefile.close(); -- Gitee