Changeset 287864 in webkit
- Timestamp:
- Jan 10, 2022, 5:36:00 PM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 16 edited
-
ChangeLog (modified) (1 diff)
-
b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp (modified) (3 diffs)
-
wasm/WasmAirIRGenerator.cpp (modified) (14 diffs)
-
wasm/WasmB3IRGenerator.cpp (modified) (4 diffs)
-
wasm/WasmB3IRGenerator.h (modified) (1 diff)
-
wasm/WasmBBQPlan.cpp (modified) (8 diffs)
-
wasm/WasmBBQPlan.h (modified) (1 diff)
-
wasm/WasmCallee.h (modified) (5 diffs)
-
wasm/WasmCalleeGroup.h (modified) (1 diff)
-
wasm/WasmFormat.h (modified) (1 diff)
-
wasm/WasmIRGeneratorHelpers.h (modified) (2 diffs)
-
wasm/WasmLLIntPlan.cpp (modified) (1 diff)
-
wasm/WasmOMGPlan.cpp (modified) (2 diffs)
-
wasm/WasmOSREntryPlan.cpp (modified) (2 diffs)
-
wasm/WasmSlowPaths.cpp (modified) (3 diffs)
-
wasm/js/JSToWasm.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r287848 r287864 1 2022-01-10 Saam Barati <sbarati@apple.com> 2 3 Allow loop tier up to the Air tier 4 https://bugs.webkit.org/show_bug.cgi?id=234587 5 <rdar://problem/86968638> 6 7 Reviewed by Yusuke Suzuki. 8 9 This patch adds loop tier up from LLInt -> Air. To implement this, we use 10 EntrySwitch to point at each loop header, making each loop an entrypoint. 11 This is unlike BBQ->OMG tier up, where we compile a special OSR entry OMG 12 callee. This seems like a good architecture for the Air tier, since we might end 13 up with slightly worse throughput, but we won't need a different compilation 14 for loops vs call entrypoints. 15 16 This patch also fixes a bug in Air's O0 register allocation where it 17 didn't properly account for all named registers in an instruction. There 18 was a silly bug where we asked each arg if it were a temp, instead of 19 asking the Inst for each of its temps, since an Arg can be an address 20 but still use temps. 21 22 * b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp: 23 (JSC::B3::Air::GenerateAndAllocateRegisters::generate): 24 * wasm/WasmAirIRGenerator.cpp: 25 (JSC::Wasm::AirIRGenerator::emitLoad): 26 (JSC::Wasm::AirIRGenerator::AirIRGenerator): 27 (JSC::Wasm::AirIRGenerator::finalizeEntrypoints): 28 (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck): 29 (JSC::Wasm::AirIRGenerator::addLoop): 30 (JSC::Wasm::parseAndCompileAir): 31 * wasm/WasmB3IRGenerator.cpp: 32 (JSC::Wasm::B3IRGenerator::B3IRGenerator): 33 (JSC::Wasm::parseAndCompileB3): 34 (JSC::Wasm::parseAndCompile): Deleted. 35 * wasm/WasmB3IRGenerator.h: 36 * wasm/WasmBBQPlan.cpp: 37 (JSC::Wasm::BBQPlan::prepareImpl): 38 (JSC::Wasm::BBQPlan::work): 39 (JSC::Wasm::BBQPlan::compileFunction): 40 (JSC::Wasm::BBQPlan::didCompleteCompilation): 41 (JSC::Wasm::BBQPlan::initializeCallees): 42 * wasm/WasmBBQPlan.h: 43 * wasm/WasmCallee.h: 44 * wasm/WasmCalleeGroup.h: 45 * wasm/WasmFormat.h: 46 * wasm/WasmIRGeneratorHelpers.h: 47 (JSC::Wasm::computeExceptionHandlerAndLoopEntrypointLocations): 48 (JSC::Wasm::computeExceptionHandlerLocations): 49 * wasm/WasmLLIntPlan.cpp: 50 (JSC::Wasm::LLIntPlan::didCompleteCompilation): 51 * wasm/WasmOMGPlan.cpp: 52 (JSC::Wasm::OMGPlan::work): 53 * wasm/WasmOSREntryPlan.cpp: 54 (JSC::Wasm::OSREntryPlan::work): 55 * wasm/WasmSlowPaths.cpp: 56 (JSC::LLInt::WASM_SLOW_PATH_DECL): 57 * wasm/js/JSToWasm.cpp: 58 (JSC::Wasm::createJSToWasmWrapper): 59 1 60 2022-01-10 Alex Christensen <achristensen@webkit.org> 2 61 -
trunk/Source/JavaScriptCore/b3/air/AirAllocateRegistersAndStackAndGenerateCode.cpp
r287806 r287864 582 582 checkConsistency(); 583 583 584 inst.forEachArg([&] (Arg& arg, Arg::Role role, Bank, Width) { 585 if (!arg.isTmp()) 586 return; 587 588 Tmp tmp = arg.tmp(); 584 inst.forEachTmp([&] (const Tmp& tmp, Arg::Role role, Bank, Width) { 589 585 if (tmp.isReg() && isDisallowedRegister(tmp.reg())) 590 586 return; … … 596 592 m_namedDefdRegs.set(tmp.reg()); 597 593 } 594 }); 595 596 inst.forEachArg([&] (Arg& arg, Arg::Role role, Bank, Width) { 597 if (!arg.isTmp()) 598 return; 599 600 Tmp tmp = arg.tmp(); 598 601 599 602 // We convert any cold uses that are already in the stack to just point to … … 694 697 // we move to providing that arg in stack form. This will allow us to fully allocate 695 698 // this inst when we rewind. 696 inst.forEach Arg([&] (Arg& arg, Arg::Role, Bank, Width) {697 if (! arg.isTmp())699 inst.forEachTmpFast([&] (Tmp& tmp) { 700 if (!tmp.isReg()) 698 701 return; 699 700 Tmp tmp = arg.tmp(); 701 if (tmp.isReg() && isDisallowedRegister(tmp.reg())) 702 if (isDisallowedRegister(tmp.reg())) 702 703 return; 703 704 if (tmp.isReg()) { 705 Tmp originalTmp = allocationSnapshot[tmp.reg()]; 706 if (originalTmp.isReg()) { 707 ASSERT(tmp.reg() == originalTmp.reg()); 708 // This means this Inst referred to this reg directly. We leave these as is. 709 return; 710 } 711 tmp = originalTmp; 712 } 713 714 if (!inst.admitsStack(arg)) { 715 arg = tmp; 704 Tmp originalTmp = allocationSnapshot[tmp.reg()]; 705 if (originalTmp.isReg()) { 706 ASSERT(tmp.reg() == originalTmp.reg()); 707 // This means this Inst referred to this reg directly. We leave these as is. 716 708 return; 717 709 } 718 719 auto& entry = m_map[tmp]; 720 if (Reg reg = entry.reg) 721 spill(tmp, reg); 722 723 arg = Arg::addr(Tmp(GPRInfo::callFrameRegister), entry.spillSlot->offsetFromFP()); 710 tmp = originalTmp; 711 }); 712 inst.forEachArg([&] (Arg& arg, Arg::Role, Bank, Width) { 713 if (arg.isTmp() && !arg.tmp().isReg() && inst.admitsStack(arg)) { 714 Tmp tmp = arg.tmp(); 715 auto& entry = m_map[tmp]; 716 if (Reg reg = entry.reg) 717 spill(tmp, reg); 718 719 arg = Arg::addr(Tmp(GPRInfo::callFrameRegister), entry.spillSlot->offsetFromFP()); 720 } 724 721 }); 725 722 -
trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
r287801 r287864 323 323 } while (0) 324 324 325 AirIRGenerator(const ModuleInformation&, B3::Procedure&, InternalFunction*, Vector<UnlinkedWasmToWasmCall>&, MemoryMode, unsigned functionIndex, TierUpCount*, const Signature& );325 AirIRGenerator(const ModuleInformation&, B3::Procedure&, InternalFunction*, Vector<UnlinkedWasmToWasmCall>&, MemoryMode, unsigned functionIndex, TierUpCount*, const Signature&, unsigned& osrEntryScratchBufferSize); 326 326 327 327 void finalizeEntrypoints(); … … 784 784 } 785 785 786 void emitLoad(Tmp base, size_t offset, TypedTmpresult)786 void emitLoad(Tmp base, size_t offset, const TypedTmp& result) 787 787 { 788 788 emitLoad(moveOpForValueType(result.type()), toB3Type(result.type()), base, offset, result.tmp()); … … 792 792 793 793 void emitEntryTierUpCheck(); 794 void emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack);794 void emitLoopTierUpCheck(uint32_t loopIndex, const Vector<TypedTmp>& liveValues); 795 795 796 796 void emitWriteBarrierForJSWrapper(); … … 885 885 StackMaps m_stackmaps; 886 886 Vector<UnlinkedHandlerInfo> m_exceptionHandlers; 887 888 Vector<std::pair<BasicBlock*, Vector<TypedTmp>>> m_loopEntryVariableData; 889 unsigned& m_osrEntryScratchBufferSize; 887 890 }; 888 891 … … 930 933 } 931 934 932 AirIRGenerator::AirIRGenerator(const ModuleInformation& info, B3::Procedure& procedure, InternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, MemoryMode mode, unsigned functionIndex, TierUpCount* tierUp, const Signature& signature )935 AirIRGenerator::AirIRGenerator(const ModuleInformation& info, B3::Procedure& procedure, InternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, MemoryMode mode, unsigned functionIndex, TierUpCount* tierUp, const Signature& signature, unsigned& osrEntryScratchBufferSize) 933 936 : m_info(info) 934 937 , m_mode(mode) … … 939 942 , m_unlinkedWasmToWasmCalls(unlinkedWasmToWasmCalls) 940 943 , m_numImportFunctions(info.importFunctionCount()) 944 , m_osrEntryScratchBufferSize(osrEntryScratchBufferSize) 941 945 { 942 946 m_currentBlock = m_code.addBlock(); … … 968 972 auto moveLocation = jit.moveWithPatch(MacroAssembler::TrustedImmPtr(nullptr), calleeGPR); 969 973 jit.addLinkTask([compilation, moveLocation] (LinkBuffer& linkBuffer) { 970 compilation->calleeMoveLocation = linkBuffer.locationOf<WasmEntryPtrTag>(moveLocation);974 compilation->calleeMoveLocations.append(linkBuffer.locationOf<WasmEntryPtrTag>(moveLocation)); 971 975 }); 972 976 jit.emitPutToCallFrameHeader(calleeGPR, CallFrameSlot::callee); … … 1073 1077 void AirIRGenerator::finalizeEntrypoints() 1074 1078 { 1075 unsigned numEntrypoints = 1 + m_catchEntrypoints.size();1079 unsigned numEntrypoints = Checked<unsigned>(1) + m_catchEntrypoints.size() + m_loopEntryVariableData.size(); 1076 1080 m_proc.setNumEntrypoints(numEntrypoints); 1077 1081 m_code.setPrologueForEntrypoint(0, Ref<B3::Air::PrologueGenerator>(*m_prologueGenerator)); 1082 for (unsigned i = 1 + m_catchEntrypoints.size(); i < numEntrypoints; ++i) 1083 m_code.setPrologueForEntrypoint(i, Ref<B3::Air::PrologueGenerator>(*m_prologueGenerator)); 1078 1084 1079 1085 if (m_catchEntrypoints.size()) { … … 1095 1101 successors.append(m_mainEntrypointStart); 1096 1102 successors.appendVector(m_catchEntrypoints); 1103 1104 for (auto& pair : m_loopEntryVariableData) { 1105 BasicBlock* loopBody = pair.first; 1106 BasicBlock* entry = m_code.addBlock(); 1107 successors.append(entry); 1108 m_currentBlock = entry; 1109 1110 auto& temps = pair.second; 1111 m_osrEntryScratchBufferSize = std::max(m_osrEntryScratchBufferSize, static_cast<unsigned>(temps.size())); 1112 Tmp basePtr = Tmp(GPRInfo::argumentGPR0); 1113 1114 for (size_t i = 0; i < temps.size(); ++i) { 1115 size_t offset = static_cast<size_t>(i) * sizeof(uint64_t); 1116 emitLoad(basePtr, offset, temps[i]); 1117 } 1118 1119 append(Jump); 1120 entry->setSuccessors(loopBody); 1121 } 1097 1122 1098 1123 RELEASE_ASSERT(numEntrypoints == successors.size()); … … 3034 3059 } 3035 3060 3036 void AirIRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack)3061 void AirIRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Vector<TypedTmp>& liveValues) 3037 3062 { 3038 3063 uint32_t outerLoopIndex = this->outerLoopIndex(); … … 3063 3088 Vector<ConstrainedTmp> patchArgs; 3064 3089 patchArgs.append(countdownPtr); 3065 3066 forEachLiveValue([&] (Tmp tmp) { 3067 patchArgs.append(ConstrainedTmp(tmp, B3::ValueRep::ColdAny)); 3068 }); 3069 for (TypedExpression value : enclosingStack) 3070 patchArgs.append(ConstrainedTmp(value.value(), B3::ValueRep::ColdAny)); 3071 for (TypedExpression value : newStack) 3072 patchArgs.append(ConstrainedTmp(value.value(), B3::ValueRep::ColdAny)); 3090 for (const TypedTmp& tmp : liveValues) 3091 patchArgs.append(ConstrainedTmp(tmp.tmp(), B3::ValueRep::ColdAny)); 3073 3092 3074 3093 TierUpCount::TriggerReason* forceEntryTrigger = &(m_tierUp->osrEntryTriggers().last()); … … 3111 3130 auto AirIRGenerator::addLoop(BlockSignature signature, Stack& enclosingStack, ControlType& block, Stack& newStack, uint32_t loopIndex) -> PartialResult 3112 3131 { 3132 RELEASE_ASSERT(loopIndex == m_loopEntryVariableData.size()); 3133 3113 3134 BasicBlock* body = m_code.addBlock(); 3114 3135 BasicBlock* continuation = m_code.addBlock(); 3115 3136 3116 3137 splitStack(signature, enclosingStack, newStack); 3138 3139 Vector<TypedTmp> liveValues; 3140 forEachLiveValue([&] (TypedTmp tmp) { 3141 liveValues.append(tmp); 3142 }); 3143 for (auto variable : enclosingStack) 3144 liveValues.append(variable); 3145 for (auto variable : newStack) 3146 liveValues.append(variable); 3147 3117 3148 ResultList results; 3118 3149 results.reserveInitialCapacity(newStack.size()); … … 3125 3156 3126 3157 m_currentBlock = body; 3127 emitLoopTierUpCheck(loopIndex, enclosingStack, newStack); 3158 emitLoopTierUpCheck(loopIndex, liveValues); 3159 3160 m_loopEntryVariableData.append(std::pair<BasicBlock*, Vector<TypedTmp>>(body, WTFMove(liveValues))); 3128 3161 3129 3162 return { }; … … 3900 3933 procedure.setOptLevel(Options::webAssemblyBBQAirOptimizationLevel()); 3901 3934 3902 AirIRGenerator irGenerator(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode, functionIndex, tierUp, signature );3935 AirIRGenerator irGenerator(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode, functionIndex, tierUp, signature, result->osrEntryScratchBufferSize); 3903 3936 FunctionParser<AirIRGenerator> parser(irGenerator, function.data.data(), function.data.size(), signature, info); 3904 3937 WASM_FAIL_IF_HELPER_FAILS(parser.parse()); -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r287801 r287864 678 678 679 679 { 680 auto* calleeMoveLocation = &compilation->calleeMoveLocation;680 auto* calleeMoveLocations = &compilation->calleeMoveLocations; 681 681 static_assert(CallFrameSlot::codeBlock * sizeof(Register) < WasmCallingConvention::headerSizeInBytes, "We rely on this here for now."); 682 682 static_assert(CallFrameSlot::callee * sizeof(Register) < WasmCallingConvention::headerSizeInBytes, "We rely on this here for now."); … … 688 688 GPRReg result = params[0].gpr(); 689 689 MacroAssembler::DataLabelPtr moveLocation = jit.moveWithPatch(MacroAssembler::TrustedImmPtr(nullptr), result); 690 jit.addLinkTask([calleeMoveLocation , moveLocation] (LinkBuffer& linkBuffer) {691 *calleeMoveLocation = linkBuffer.locationOf<WasmEntryPtrTag>(moveLocation);690 jit.addLinkTask([calleeMoveLocations, moveLocation] (LinkBuffer& linkBuffer) { 691 calleeMoveLocations->append(linkBuffer.locationOf<WasmEntryPtrTag>(moveLocation)); 692 692 }); 693 693 }); … … 3139 3139 } 3140 3140 3141 Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile (CompilationContext& compilationContext, const FunctionData& function, const Signature& signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, unsigned& osrEntryScratchBufferSize, const ModuleInformation& info, MemoryMode mode, CompilationMode compilationMode, uint32_t functionIndex, uint32_t loopIndexForOSREntry, TierUpCount* tierUp)3141 Expected<std::unique_ptr<InternalFunction>, String> parseAndCompileB3(CompilationContext& compilationContext, const FunctionData& function, const Signature& signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const ModuleInformation& info, MemoryMode mode, CompilationMode compilationMode, uint32_t functionIndex, uint32_t loopIndexForOSREntry, TierUpCount* tierUp) 3142 3142 { 3143 3143 auto result = makeUnique<InternalFunction>(); … … 3176 3176 : Options::webAssemblyOMGOptimizationLevel()); 3177 3177 3178 B3IRGenerator irGenerator(info, procedure, result.get(), unlinkedWasmToWasmCalls, osrEntryScratchBufferSize, mode, compilationMode, functionIndex, loopIndexForOSREntry, tierUp);3178 B3IRGenerator irGenerator(info, procedure, result.get(), unlinkedWasmToWasmCalls, result->osrEntryScratchBufferSize, mode, compilationMode, functionIndex, loopIndexForOSREntry, tierUp); 3179 3179 FunctionParser<B3IRGenerator> parser(irGenerator, function.data.data(), function.data.size(), signature, info); 3180 3180 WASM_FAIL_IF_HELPER_FAILS(parser.parse()); -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h
r287801 r287864 58 58 }; 59 59 60 Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile (CompilationContext&, const FunctionData&, const Signature&, Vector<UnlinkedWasmToWasmCall>&, unsigned& osrEntryScratchBufferSize, const ModuleInformation&, MemoryMode, CompilationMode, uint32_t functionIndex, uint32_t loopIndexForOSREntry, TierUpCount* = nullptr);60 Expected<std::unique_ptr<InternalFunction>, String> parseAndCompileB3(CompilationContext&, const FunctionData&, const Signature&, Vector<UnlinkedWasmToWasmCall>&, const ModuleInformation&, MemoryMode, CompilationMode, uint32_t functionIndex, uint32_t loopIndexForOSREntry, TierUpCount* = nullptr); 61 61 62 62 void computePCToCodeOriginMap(CompilationContext&, LinkBuffer&); -
trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp
r287801 r287864 65 65 if (!tryReserveCapacity(m_wasmInternalFunctions, functions.size(), " WebAssembly functions") 66 66 || !tryReserveCapacity(m_compilationContexts, functions.size(), " compilation contexts") 67 || !tryReserveCapacity(m_tierUpCounts, functions.size(), " tier-up counts")) 67 || !tryReserveCapacity(m_tierUpCounts, functions.size(), " tier-up counts") 68 || !tryReserveCapacity(m_allLoopEntrypoints, functions.size(), " loop entrypoints")) 68 69 return false; 69 70 … … 72 73 m_compilationContexts.resize(functions.size()); 73 74 m_tierUpCounts.resize(functions.size()); 75 m_allLoopEntrypoints.resize(functions.size()); 74 76 75 77 return true; … … 114 116 115 117 Vector<CodeLocationLabel<ExceptionHandlerPtrTag>> exceptionHandlerLocations; 116 computeExceptionHandlerLocations(exceptionHandlerLocations, function.get(), context, linkBuffer); 118 Vector<CodeLocationLabel<WasmEntryPtrTag>> loopEntrypointLocations; 119 computeExceptionHandlerAndLoopEntrypointLocations(exceptionHandlerLocations, loopEntrypointLocations, function.get(), context, linkBuffer); 117 120 118 121 computePCToCodeOriginMap(context, linkBuffer); … … 127 130 MacroAssemblerCodePtr<WasmEntryPtrTag> entrypoint; 128 131 { 129 Ref<BBQCallee> callee = BBQCallee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(tierUp), WTFMove(unlinkedWasmToWasmCalls), WTFMove(function->stackmaps), WTFMove(function->exceptionHandlers), WTFMove(exceptionHandlerLocations)); 130 MacroAssembler::repatchPointer(function->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr())); 132 Ref<BBQCallee> callee = BBQCallee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(tierUp), WTFMove(unlinkedWasmToWasmCalls), WTFMove(function->stackmaps), WTFMove(function->exceptionHandlers), WTFMove(exceptionHandlerLocations), WTFMove(loopEntrypointLocations), function->osrEntryScratchBufferSize); 133 for (auto& moveLocation : function->calleeMoveLocations) 134 MacroAssembler::repatchPointer(moveLocation, CalleeBits::boxWasm(callee.ptr())); 131 135 entrypoint = callee->entrypoint(); 132 136 … … 197 201 ASSERT_UNUSED(functionIndexSpace, m_moduleInformation->signatureIndexFromFunctionIndexSpace(functionIndexSpace) == signatureIndex); 198 202 Expected<std::unique_ptr<InternalFunction>, String> parseAndCompileResult; 199 unsigned osrEntryScratchBufferSize = 0;200 203 201 204 // FIXME: Some webpages use very large Wasm module, and it exhausts all executable memory in ARM64 devices since the size of executable memory region is only limited to 128MB. … … 209 212 210 213 if (forceUsingB3) 211 parseAndCompileResult = parseAndCompile (context, function, signature, unlinkedWasmToWasmCalls, osrEntryScratchBufferSize, m_moduleInformation.get(), m_mode, CompilationMode::BBQMode, functionIndex, UINT32_MAX, tierUp);214 parseAndCompileResult = parseAndCompileB3(context, function, signature, unlinkedWasmToWasmCalls, m_moduleInformation.get(), m_mode, CompilationMode::BBQMode, functionIndex, UINT32_MAX, tierUp); 212 215 else 213 216 parseAndCompileResult = parseAndCompileAir(context, function, signature, unlinkedWasmToWasmCalls, m_moduleInformation.get(), m_mode, functionIndex, tierUp); … … 242 245 } 243 246 244 computeExceptionHandler Locations(m_exceptionHandlerLocations[functionIndex], function, context, linkBuffer);247 computeExceptionHandlerAndLoopEntrypointLocations(m_exceptionHandlerLocations[functionIndex], m_allLoopEntrypoints[functionIndex], function, context, linkBuffer); 245 248 246 249 computePCToCodeOriginMap(context, linkBuffer); … … 285 288 if (auto embedderToWasmFunction = m_embedderToWasmInternalFunctions.get(internalFunctionIndex)) { 286 289 embedderEntrypointCallee = EmbedderEntrypointCallee::create(WTFMove(embedderToWasmFunction->entrypoint)); 287 MacroAssembler::repatchPointer(embedderToWasmFunction->calleeMoveLocation, CalleeBits::boxWasm(embedderEntrypointCallee.get())); 290 for (auto& moveLocation : embedderToWasmFunction->calleeMoveLocations) 291 MacroAssembler::repatchPointer(moveLocation, CalleeBits::boxWasm(embedderEntrypointCallee.get())); 288 292 } 289 293 290 294 InternalFunction* function = m_wasmInternalFunctions[internalFunctionIndex].get(); 291 295 size_t functionIndexSpace = internalFunctionIndex + m_moduleInformation->importFunctionCount(); 292 Ref<BBQCallee> wasmEntrypointCallee = BBQCallee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(m_tierUpCounts[internalFunctionIndex]), WTFMove(m_unlinkedWasmToWasmCalls[internalFunctionIndex]), WTFMove(function->stackmaps), WTFMove(function->exceptionHandlers), WTFMove(m_exceptionHandlerLocations[internalFunctionIndex])); 293 MacroAssembler::repatchPointer(function->calleeMoveLocation, CalleeBits::boxWasm(wasmEntrypointCallee.ptr())); 296 Ref<BBQCallee> wasmEntrypointCallee = BBQCallee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(m_tierUpCounts[internalFunctionIndex]), WTFMove(m_unlinkedWasmToWasmCalls[internalFunctionIndex]), WTFMove(function->stackmaps), WTFMove(function->exceptionHandlers), WTFMove(m_exceptionHandlerLocations[internalFunctionIndex]), WTFMove(m_allLoopEntrypoints[internalFunctionIndex]), function->osrEntryScratchBufferSize); 297 298 for (auto& moveLocation : function->calleeMoveLocations) 299 MacroAssembler::repatchPointer(moveLocation, CalleeBits::boxWasm(wasmEntrypointCallee.ptr())); 294 300 295 301 if (m_compilationContexts[internalFunctionIndex].pcToCodeOriginMap) -
trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.h
r287122 r287864 88 88 Vector<CompilationContext> m_compilationContexts; 89 89 Vector<std::unique_ptr<TierUpCount>> m_tierUpCounts; 90 Vector<Vector<CodeLocationLabel<WasmEntryPtrTag>>> m_allLoopEntrypoints; 90 91 91 92 RefPtr<CalleeGroup> m_calleeGroup { nullptr }; -
trunk/Source/JavaScriptCore/wasm/WasmCallee.h
r287459 r287864 173 173 class BBQCallee final : public OptimizingJITCallee { 174 174 public: 175 static Ref<BBQCallee> create(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, std::unique_ptr<TierUpCount>&& tierUpCount, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, StackMaps&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations )176 { 177 return adoptRef(*new BBQCallee(WTFMove(entrypoint), index, WTFMove(name), WTFMove(tierUpCount), WTFMove(unlinkedCalls), WTFMove(stackmaps), WTFMove(exceptionHandlers), WTFMove(exceptionHandlerLocations) ));175 static Ref<BBQCallee> create(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, std::unique_ptr<TierUpCount>&& tierUpCount, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, StackMaps&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations, Vector<CodeLocationLabel<WasmEntryPtrTag>>&& loopEntrypoints, unsigned osrEntryScratchBufferSize) 176 { 177 return adoptRef(*new BBQCallee(WTFMove(entrypoint), index, WTFMove(name), WTFMove(tierUpCount), WTFMove(unlinkedCalls), WTFMove(stackmaps), WTFMove(exceptionHandlers), WTFMove(exceptionHandlerLocations), WTFMove(loopEntrypoints), osrEntryScratchBufferSize)); 178 178 } 179 179 … … 195 195 TierUpCount* tierUpCount() { return m_tierUpCount.get(); } 196 196 197 private: 198 BBQCallee(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, std::unique_ptr<TierUpCount>&& tierUpCount, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, StackMaps&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations) 197 const Vector<CodeLocationLabel<WasmEntryPtrTag>>& loopEntrypoints() { return m_loopEntrypoints; } 198 199 unsigned osrEntryScratchBufferSize() const { return m_osrEntryScratchBufferSize; } 200 201 private: 202 BBQCallee(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, std::unique_ptr<TierUpCount>&& tierUpCount, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, StackMaps&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations, Vector<CodeLocationLabel<WasmEntryPtrTag>>&& loopEntrypoints, unsigned osrEntryScratchBufferSize) 199 203 : OptimizingJITCallee(Wasm::CompilationMode::BBQMode, WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls), WTFMove(stackmaps), WTFMove(exceptionHandlers), WTFMove(exceptionHandlerLocations)) 200 204 , m_tierUpCount(WTFMove(tierUpCount)) 205 , m_loopEntrypoints(WTFMove(loopEntrypoints)) 206 , m_osrEntryScratchBufferSize(osrEntryScratchBufferSize) 201 207 { 202 208 } … … 205 211 RefPtr<OMGCallee> m_replacement; 206 212 std::unique_ptr<TierUpCount> m_tierUpCount; 213 Vector<CodeLocationLabel<WasmEntryPtrTag>> m_loopEntrypoints; 214 unsigned m_osrEntryScratchBufferSize { 0 }; 207 215 bool m_didStartCompilingOSREntryCallee { false }; 208 216 }; … … 268 276 #if ENABLE(WEBASSEMBLY_B3JIT) 269 277 JITCallee* replacement(MemoryMode mode) { return m_replacements[static_cast<uint8_t>(mode)].get(); } 270 void setReplacement(Ref< JITCallee>&& replacement, MemoryMode mode)278 void setReplacement(Ref<OptimizingJITCallee>&& replacement, MemoryMode mode) 271 279 { 272 280 m_replacements[static_cast<uint8_t>(mode)] = WTFMove(replacement); … … 303 311 304 312 #if ENABLE(WEBASSEMBLY_B3JIT) 305 RefPtr< JITCallee> m_replacements[Wasm::NumberOfMemoryModes];313 RefPtr<OptimizingJITCallee> m_replacements[Wasm::NumberOfMemoryModes]; 306 314 RefPtr<OSREntryCallee> m_osrEntryCallees[Wasm::NumberOfMemoryModes]; 307 315 #endif -
trunk/Source/JavaScriptCore/wasm/WasmCalleeGroup.h
r287379 r287864 184 184 std::atomic<bool> m_compilationFinished { false }; 185 185 String m_errorMessage; 186 public: 186 187 Lock m_lock; 187 188 }; -
trunk/Source/JavaScriptCore/wasm/WasmFormat.h
r285065 r287864 444 444 struct InternalFunction { 445 445 WTF_MAKE_STRUCT_FAST_ALLOCATED; 446 CodeLocationDataLabelPtr<WasmEntryPtrTag> calleeMoveLocation;446 Vector<CodeLocationDataLabelPtr<WasmEntryPtrTag>> calleeMoveLocations; 447 447 StackMaps stackmaps; 448 448 Vector<UnlinkedHandlerInfo> exceptionHandlers; 449 449 Entrypoint entrypoint; 450 unsigned osrEntryScratchBufferSize { 0 }; 450 451 }; 451 452 -
trunk/Source/JavaScriptCore/wasm/WasmIRGeneratorHelpers.h
r287801 r287864 64 64 65 65 66 static inline void computeExceptionHandler Locations(Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>& handlers, const InternalFunction* function, const CompilationContext& context, LinkBuffer& linkBuffer)66 static inline void computeExceptionHandlerAndLoopEntrypointLocations(Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>& handlers, Vector<CodeLocationLabel<WasmEntryPtrTag>>& loopEntrypoints, const InternalFunction* function, const CompilationContext& context, LinkBuffer& linkBuffer) 67 67 { 68 68 if (!context.procedure) 69 69 return; 70 70 71 unsigned entrypointIndex = 0;71 unsigned entrypointIndex = 1; 72 72 unsigned numEntrypoints = context.procedure->numEntrypoints(); 73 73 for (const UnlinkedHandlerInfo& handlerInfo : function->exceptionHandlers) { 74 RELEASE_ASSERT(entrypointIndex < numEntrypoints);75 74 if (handlerInfo.m_type == HandlerType::Delegate) { 76 75 handlers.append({ }); … … 78 77 } 79 78 79 RELEASE_ASSERT(entrypointIndex < numEntrypoints); 80 handlers.append(linkBuffer.locationOf<ExceptionHandlerPtrTag>(context.procedure->code().entrypointLabel(entrypointIndex))); 80 81 ++entrypointIndex; 81 handlers.append(linkBuffer.locationOf<ExceptionHandlerPtrTag>(context.procedure->code().entrypointLabel(entrypointIndex))); 82 } 83 RELEASE_ASSERT(entrypointIndex == numEntrypoints - 1); 82 } 83 84 for (; entrypointIndex < numEntrypoints; ++entrypointIndex) 85 loopEntrypoints.append(linkBuffer.locationOf<WasmEntryPtrTag>(context.procedure->code().entrypointLabel(entrypointIndex))); 86 } 87 88 static inline void computeExceptionHandlerLocations(Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>& handlers, const InternalFunction* function, const CompilationContext& context, LinkBuffer& linkBuffer) 89 { 90 Vector<CodeLocationLabel<WasmEntryPtrTag>> ignored; 91 computeExceptionHandlerAndLoopEntrypointLocations(handlers, ignored, function, context, linkBuffer); 84 92 } 85 93 -
trunk/Source/JavaScriptCore/wasm/WasmLLIntPlan.cpp
r287513 r287864 169 169 // FIXME: remove this repatchPointer - just pass in the callee directly 170 170 // https://bugs.webkit.org/show_bug.cgi?id=166462 171 if (function->calleeMoveLocation)172 MacroAssembler::repatchPointer( function->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr()));171 for (auto& moveLocation : function->calleeMoveLocations) 172 MacroAssembler::repatchPointer(moveLocation, CalleeBits::boxWasm(callee.ptr())); 173 173 174 174 auto result = m_embedderCallees.add(functionIndex, WTFMove(callee)); -
trunk/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp
r287801 r287864 73 73 74 74 Vector<UnlinkedWasmToWasmCall> unlinkedCalls; 75 unsigned osrEntryScratchBufferSize;76 75 CompilationContext context; 77 auto parseAndCompileResult = parseAndCompile (context, function, signature, unlinkedCalls, osrEntryScratchBufferSize, m_moduleInformation.get(), m_mode, CompilationMode::OMGMode, m_functionIndex, UINT32_MAX);76 auto parseAndCompileResult = parseAndCompileB3(context, function, signature, unlinkedCalls, m_moduleInformation.get(), m_mode, CompilationMode::OMGMode, m_functionIndex, UINT32_MAX); 78 77 79 78 if (UNLIKELY(!parseAndCompileResult)) { … … 107 106 ASSERT(m_calleeGroup.ptr() == m_module->calleeGroupFor(mode())); 108 107 Ref<OMGCallee> callee = OMGCallee::create(WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(unlinkedCalls), WTFMove(internalFunction->stackmaps), WTFMove(internalFunction->exceptionHandlers), WTFMove(exceptionHandlerLocations)); 109 MacroAssembler::repatchPointer(internalFunction->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr())); 108 for (auto& moveLocation : internalFunction->calleeMoveLocations) 109 MacroAssembler::repatchPointer(moveLocation, CalleeBits::boxWasm(callee.ptr())); 110 110 entrypoint = callee->entrypoint(); 111 111 -
trunk/Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp
r287801 r287864 78 78 Vector<UnlinkedWasmToWasmCall> unlinkedCalls; 79 79 CompilationContext context; 80 unsigned osrEntryScratchBufferSize = 0; 81 auto parseAndCompileResult = parseAndCompile(context, function, signature, unlinkedCalls, osrEntryScratchBufferSize, m_moduleInformation.get(), m_mode, targetCompilationMode, m_functionIndex, m_loopIndex); 80 auto parseAndCompileResult = parseAndCompileB3(context, function, signature, unlinkedCalls, m_moduleInformation.get(), m_mode, targetCompilationMode, m_functionIndex, m_loopIndex); 82 81 83 82 if (UNLIKELY(!parseAndCompileResult)) { … … 106 105 107 106 ASSERT(m_calleeGroup.ptr() == m_module->calleeGroupFor(mode())); 108 Ref<OSREntryCallee> callee = OSREntryCallee::create(targetCompilationMode, WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), osrEntryScratchBufferSize, m_loopIndex, WTFMove(unlinkedCalls), WTFMove(internalFunction->stackmaps), WTFMove(internalFunction->exceptionHandlers), WTFMove(exceptionHandlerLocations));107 Ref<OSREntryCallee> callee = OSREntryCallee::create(targetCompilationMode, WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), internalFunction->osrEntryScratchBufferSize, m_loopIndex, WTFMove(unlinkedCalls), WTFMove(internalFunction->stackmaps), WTFMove(internalFunction->exceptionHandlers), WTFMove(exceptionHandlerLocations)); 109 108 { 110 MacroAssembler::repatchPointer(internalFunction->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr())); 109 for (auto& moveLocation : internalFunction->calleeMoveLocations) 110 MacroAssembler::repatchPointer(moveLocation, CalleeBits::boxWasm(callee.ptr())); 111 111 112 112 Locker locker { m_calleeGroup->m_lock }; -
trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp
r287459 r287864 181 181 dataLogLnIf(Options::verboseOSR(), *callee, ": Entered loop_osr with tierUpCounter = ", callee->tierUpCounter()); 182 182 183 unsigned loopOSREntryBytecodeOffset = callee->bytecodeOffset(pc);184 const auto& osrEntryData = tierUpCounter.osrEntryDataForLoop(loopOSREntryBytecodeOffset);185 186 183 if (!tierUpCounter.checkIfOptimizationThresholdReached()) { 187 184 dataLogLnIf(Options::verboseOSR(), " JIT threshold should be lifted."); … … 189 186 } 190 187 191 const auto doOSREntry = [&](Wasm::OSREntryCallee* osrEntryCallee) { 192 if (osrEntryCallee->loopIndex() != osrEntryData.loopIndex) 188 unsigned loopOSREntryBytecodeOffset = callee->bytecodeOffset(pc); 189 const auto& osrEntryData = tierUpCounter.osrEntryDataForLoop(loopOSREntryBytecodeOffset); 190 191 if (Options::wasmLLIntTiersUpToBBQ()) { 192 if (!jitCompileAndSetHeuristics(callee, instance)) 193 193 WASM_RETURN_TWO(nullptr, nullptr); 194 194 195 size_t osrEntryScratchBufferSize = osrEntryCallee->osrEntryScratchBufferSize(); 196 RELEASE_ASSERT(osrEntryScratchBufferSize == osrEntryData.values.size()); 195 Wasm::BBQCallee* bbqCallee; 196 { 197 Locker locker { instance->calleeGroup()->m_lock }; 198 bbqCallee = instance->calleeGroup()->bbqCallee(locker, callee->functionIndex()); 199 } 200 RELEASE_ASSERT(bbqCallee); 201 202 size_t osrEntryScratchBufferSize = bbqCallee->osrEntryScratchBufferSize(); 203 RELEASE_ASSERT(osrEntryScratchBufferSize >= osrEntryData.values.size()); 197 204 uint64_t* buffer = instance->context()->scratchBufferForSize(osrEntryScratchBufferSize); 198 205 if (!buffer) 199 206 WASM_RETURN_TWO(nullptr, nullptr); 207 RELEASE_ASSERT(osrEntryData.loopIndex < bbqCallee->loopEntrypoints().size()); 200 208 201 209 uint32_t index = 0; … … 203 211 buffer[index++] = READ(reg).encodedJSValue(); 204 212 205 WASM_RETURN_TWO(buffer, osrEntryCallee->entrypoint().executableAddress()); 206 }; 207 208 if (auto* osrEntryCallee = callee->osrEntryCallee(instance->memory()->mode())) 209 return doOSREntry(osrEntryCallee); 210 211 bool compile = false; 212 { 213 Locker locker { tierUpCounter.m_lock }; 214 switch (tierUpCounter.m_loopCompilationStatus) { 215 case Wasm::LLIntTierUpCounter::CompilationStatus::NotCompiled: 216 compile = true; 217 tierUpCounter.m_loopCompilationStatus = Wasm::LLIntTierUpCounter::CompilationStatus::Compiling; 218 break; 219 case Wasm::LLIntTierUpCounter::CompilationStatus::Compiling: 220 tierUpCounter.optimizeAfterWarmUp(); 221 break; 222 case Wasm::LLIntTierUpCounter::CompilationStatus::Compiled: 223 break; 213 WASM_RETURN_TWO(buffer, bbqCallee->loopEntrypoints()[osrEntryData.loopIndex].executableAddress()); 214 } else { 215 const auto doOSREntry = [&](Wasm::OSREntryCallee* osrEntryCallee) { 216 if (osrEntryCallee->loopIndex() != osrEntryData.loopIndex) 217 WASM_RETURN_TWO(nullptr, nullptr); 218 219 size_t osrEntryScratchBufferSize = osrEntryCallee->osrEntryScratchBufferSize(); 220 RELEASE_ASSERT(osrEntryScratchBufferSize == osrEntryData.values.size()); 221 uint64_t* buffer = instance->context()->scratchBufferForSize(osrEntryScratchBufferSize); 222 if (!buffer) 223 WASM_RETURN_TWO(nullptr, nullptr); 224 225 uint32_t index = 0; 226 for (VirtualRegister reg : osrEntryData.values) 227 buffer[index++] = READ(reg).encodedJSValue(); 228 229 WASM_RETURN_TWO(buffer, osrEntryCallee->entrypoint().executableAddress()); 230 }; 231 232 if (auto* osrEntryCallee = callee->osrEntryCallee(instance->memory()->mode())) 233 return doOSREntry(osrEntryCallee); 234 235 bool compile = false; 236 { 237 Locker locker { tierUpCounter.m_lock }; 238 switch (tierUpCounter.m_loopCompilationStatus) { 239 case Wasm::LLIntTierUpCounter::CompilationStatus::NotCompiled: 240 compile = true; 241 tierUpCounter.m_loopCompilationStatus = Wasm::LLIntTierUpCounter::CompilationStatus::Compiling; 242 break; 243 case Wasm::LLIntTierUpCounter::CompilationStatus::Compiling: 244 tierUpCounter.optimizeAfterWarmUp(); 245 break; 246 case Wasm::LLIntTierUpCounter::CompilationStatus::Compiled: 247 break; 248 } 224 249 } 225 } 226 227 if (compile) {228 Ref<Wasm::Plan> plan = adoptRef(*static_cast<Wasm::Plan*>(new Wasm::OSREntryPlan(instance->context(), Ref<Wasm::Module>(instance->module()), Ref<Wasm::Callee>(*callee), callee->functionIndex(), osrEntryData.loopIndex, instance->memory()->mode(), Wasm::Plan::dontFinalize())));229 Wasm::ensureWorklist().enqueue(plan.copyRef());230 if (UNLIKELY(!Options::useConcurrentJIT()))231 plan->waitForCompletion();232 else233 tierUpCounter.optimizeAfterWarmUp();234 } 235 236 if (auto* osrEntryCallee = callee->osrEntryCallee(instance->memory()->mode()))237 return doOSREntry(osrEntryCallee); 238 239 WASM_RETURN_TWO(nullptr, nullptr);250 251 if (compile) { 252 Ref<Wasm::Plan> plan = adoptRef(*static_cast<Wasm::Plan*>(new Wasm::OSREntryPlan(instance->context(), Ref<Wasm::Module>(instance->module()), Ref<Wasm::Callee>(*callee), callee->functionIndex(), osrEntryData.loopIndex, instance->memory()->mode(), Wasm::Plan::dontFinalize()))); 253 Wasm::ensureWorklist().enqueue(plan.copyRef()); 254 if (UNLIKELY(!Options::useConcurrentJIT())) 255 plan->waitForCompletion(); 256 else 257 tierUpCounter.optimizeAfterWarmUp(); 258 } 259 260 if (auto* osrEntryCallee = callee->osrEntryCallee(instance->memory()->mode())) 261 return doOSREntry(osrEntryCallee); 262 263 WASM_RETURN_TWO(nullptr, nullptr); 264 } 240 265 } 241 266 -
trunk/Source/JavaScriptCore/wasm/js/JSToWasm.cpp
r284935 r287864 179 179 MacroAssembler::DataLabelPtr calleeMoveLocation = jit.moveWithPatch(MacroAssembler::TrustedImmPtr(nullptr), GPRInfo::nonPreservedNonReturnGPR); 180 180 jit.emitPutToCallFrameHeader(GPRInfo::nonPreservedNonReturnGPR, CallFrameSlot::callee); 181 CodeLocationDataLabelPtr<WasmEntryPtrTag>* linkedCalleeMove = &result->calleeMoveLocation;181 Vector<CodeLocationDataLabelPtr<WasmEntryPtrTag>>* linkedCalleeMove = &result->calleeMoveLocations; 182 182 jit.addLinkTask([=] (LinkBuffer& linkBuffer) { 183 *linkedCalleeMove = linkBuffer.locationOf<WasmEntryPtrTag>(calleeMoveLocation);183 linkedCalleeMove->append(linkBuffer.locationOf<WasmEntryPtrTag>(calleeMoveLocation)); 184 184 }); 185 185
Note:
See TracChangeset
for help on using the changeset viewer.