Changeset 249661 in webkit
- Timestamp:
- Sep 9, 2019 1:32:56 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 10 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r249650 r249661 1 2019-09-07 Keith Miller <keith_miller@apple.com> 2 3 OSR entry into wasm misses some contexts 4 https://bugs.webkit.org/show_bug.cgi?id=201569 5 6 Reviewed by Yusuke Suzuki. 7 8 Add a new harness and wast and the generated wasm file for 9 testing. The idea long term is to make it easy to test by creating 10 a C file and converting it to a wast then modify that to produce a 11 test. 12 13 * wasm.yaml: 14 * wasm/wast-tests/harness.js: Added. 15 (async.runWasmFile): 16 * wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wasm: Added. 17 * wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wast: Added. 18 * wasm/wast-tests/osr-entry-inner-loop-branch-above.wasm: Added. 19 * wasm/wast-tests/osr-entry-inner-loop-branch-above.wast: Added. 20 * wasm/wast-tests/osr-entry-inner-loop.wasm: Added. 21 * wasm/wast-tests/osr-entry-inner-loop.wast: Added. 22 * wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wasm: Added. 23 * wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wast: Added. 24 1 25 2019-09-09 Yusuke Suzuki <ysuzuki@apple.com> 2 26 -
trunk/JSTests/wasm.yaml
r246645 r249661 22 22 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 23 24 - path: wasm/ self-test/25 cmd: runWebAssembly Suite unless parseRunCommands24 - path: wasm/wast-tests/ 25 cmd: runWebAssemblyWithHarness 26 26 - path: wasm/js-api/ 27 27 cmd: runWebAssemblySuite unless parseRunCommands … … 44 44 - path: wasm/modules/ 45 45 cmd: runWebAssembly unless parseRunCommands 46 - path: wasm/self-test/ 47 cmd: runWebAssemblySuite unless parseRunCommands 46 48 47 49 - path: wasm/spec-tests/address.wast.js … … 186 188 - path: wasm/modules/run-from-wasm.wasm 187 189 cmd: runWebAssembly 190 -
trunk/Source/JavaScriptCore/ChangeLog
r249650 r249661 1 2019-09-07 Keith Miller <keith_miller@apple.com> 2 3 OSR entry into wasm misses some contexts 4 https://bugs.webkit.org/show_bug.cgi?id=201569 5 6 Reviewed by Yusuke Suzuki. 7 8 This patch fixes an issue where we could fail to capture some of 9 our contexts when OSR entering into wasm code. Before we would 10 only capture the state of the block immediately surrounding the 11 entrance loop block header. We actually need to capture all 12 enclosed stacks. 13 14 Additionally, we don't need to use variables for all the captured 15 values. We can use a Phi and insert an upsilon just below the 16 captured value. 17 18 * interpreter/CallFrame.h: 19 * jsc.cpp: 20 (GlobalObject::finishCreation): 21 (functionCallerIsOMGCompiled): 22 * wasm/WasmAirIRGenerator.cpp: 23 (JSC::Wasm::AirIRGenerator::AirIRGenerator): 24 (JSC::Wasm::AirIRGenerator::emitEntryTierUpCheck): 25 (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck): 26 (JSC::Wasm::AirIRGenerator::addLoop): 27 * wasm/WasmB3IRGenerator.cpp: 28 (JSC::Wasm::B3IRGenerator::createStack): 29 (JSC::Wasm::B3IRGenerator::B3IRGenerator): 30 (JSC::Wasm::B3IRGenerator::addConstant): 31 (JSC::Wasm::B3IRGenerator::emitEntryTierUpCheck): 32 (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck): 33 (JSC::Wasm::B3IRGenerator::addLoop): 34 (JSC::Wasm::B3IRGenerator::addEndToUnreachable): 35 (JSC::Wasm::dumpExpressionStack): 36 (JSC::Wasm::B3IRGenerator::dump): 37 (JSC::Wasm::B3IRGenerator::Stack::Stack): Deleted. 38 (JSC::Wasm::B3IRGenerator::Stack::append): Deleted. 39 (JSC::Wasm::B3IRGenerator::Stack::takeLast): Deleted. 40 (JSC::Wasm::B3IRGenerator::Stack::last): Deleted. 41 (JSC::Wasm::B3IRGenerator::Stack::size const): Deleted. 42 (JSC::Wasm::B3IRGenerator::Stack::isEmpty const): Deleted. 43 (JSC::Wasm::B3IRGenerator::Stack::convertToExpressionList): Deleted. 44 (JSC::Wasm::B3IRGenerator::Stack::at const): Deleted. 45 (JSC::Wasm::B3IRGenerator::Stack::variableAt const): Deleted. 46 (JSC::Wasm::B3IRGenerator::Stack::shrink): Deleted. 47 (JSC::Wasm::B3IRGenerator::Stack::swap): Deleted. 48 (JSC::Wasm::B3IRGenerator::Stack::dump const): Deleted. 49 * wasm/WasmFunctionParser.h: 50 (JSC::Wasm::FunctionParser::controlStack): 51 1 52 2019-09-09 Yusuke Suzuki <ysuzuki@apple.com> 2 53 -
trunk/Source/JavaScriptCore/interpreter/CallFrame.h
r246505 r249661 133 133 JSGlobalObject* wasmAwareLexicalGlobalObject(VM&); 134 134 135 bool isAnyWasmCallee();135 JS_EXPORT_PRIVATE bool isAnyWasmCallee(); 136 136 137 137 // Global object in which the currently executing code was defined. -
trunk/Source/JavaScriptCore/jsc.cpp
r249612 r249661 28 28 #include "ButterflyInlines.h" 29 29 #include "BytecodeCacheError.h" 30 #include "CallFrameInlines.h" 30 31 #include "CatchScope.h" 31 32 #include "CodeBlock.h" … … 321 322 static EncodedJSValue JSC_HOST_CALL functionOptimizeNextInvocation(ExecState*); 322 323 static EncodedJSValue JSC_HOST_CALL functionNumberOfDFGCompiles(ExecState*); 324 static EncodedJSValue JSC_HOST_CALL functionCallerIsOMGCompiled(ExecState*); 323 325 static EncodedJSValue JSC_HOST_CALL functionJSCOptions(ExecState*); 324 326 static EncodedJSValue JSC_HOST_CALL functionReoptimizationRetryCount(ExecState*); … … 542 544 addFunction(vm, "noOSRExitFuzzing", functionNoOSRExitFuzzing, 1); 543 545 addFunction(vm, "numberOfDFGCompiles", functionNumberOfDFGCompiles, 1); 546 addFunction(vm, "callerIsOMGCompiled", functionCallerIsOMGCompiled, 0); 544 547 addFunction(vm, "jscOptions", functionJSCOptions, 0); 545 548 addFunction(vm, "optimizeNextInvocation", functionOptimizeNextInvocation, 1); … … 1728 1731 } 1729 1732 1733 EncodedJSValue JSC_HOST_CALL functionCallerIsOMGCompiled(ExecState* exec) 1734 { 1735 VM& vm = exec->vm(); 1736 auto scope = DECLARE_THROW_SCOPE(vm); 1737 1738 if (!Options::useBBQTierUpChecks()) 1739 return JSValue::encode(jsBoolean(true)); 1740 1741 CallerFunctor wasmToJSFrame; 1742 StackVisitor::visit(exec, &vm, wasmToJSFrame); 1743 if (!wasmToJSFrame.callerFrame()->isAnyWasmCallee()) 1744 return throwVMError(exec, scope, "caller is not a wasm->js import function"); 1745 1746 // We have a wrapper frame that we generate for imports. If we ever can direct call from wasm we would need to change this. 1747 ASSERT(!wasmToJSFrame.callerFrame()->callee().isWasm()); 1748 CallerFunctor wasmFrame; 1749 StackVisitor::visit(wasmToJSFrame.callerFrame(), &vm, wasmFrame); 1750 ASSERT(wasmFrame.callerFrame()->callee().isWasm()); 1751 #if ENABLE(WEBASSEMBLY) 1752 auto mode = wasmFrame.callerFrame()->callee().asWasmCallee()->compilationMode(); 1753 return JSValue::encode(jsBoolean(mode == Wasm::CompilationMode::OMGMode || mode == Wasm::CompilationMode::OMGForOSREntryMode)); 1754 #endif 1755 RELEASE_ASSERT_NOT_REACHED(); 1756 } 1757 1730 1758 Message::Message(ArrayBufferContents&& contents, int32_t index) 1731 1759 : m_contents(WTFMove(contents)) -
trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
r249221 r249661 592 592 void emitThrowException(CCallHelpers&, ExceptionType); 593 593 594 void emitEntryTierUpCheck( int32_t incrementCount, B3::Origin);595 void emitLoopTierUpCheck( int32_t incrementCount, const Stack&, uint32_t, uint32_t, B3::Origin);594 void emitEntryTierUpCheck(); 595 void emitLoopTierUpCheck(uint32_t loopIndex); 596 596 597 597 void emitWriteBarrierForJSWrapper(); … … 853 853 }); 854 854 855 emitEntryTierUpCheck( TierUpCount::functionEntryIncrement(), B3::Origin());855 emitEntryTierUpCheck(); 856 856 } 857 857 … … 1604 1604 } 1605 1605 1606 void AirIRGenerator::emitEntryTierUpCheck(int32_t incrementCount, B3::Origin origin) 1607 { 1608 UNUSED_PARAM(origin); 1609 1606 void AirIRGenerator::emitEntryTierUpCheck() 1607 { 1610 1608 if (!m_tierUp) 1611 1609 return; … … 1625 1623 AllowMacroScratchRegisterUsage allowScratch(jit); 1626 1624 1627 CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32( incrementCount), CCallHelpers::Address(params[0].gpr()));1625 CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(TierUpCount::functionEntryIncrement()), CCallHelpers::Address(params[0].gpr())); 1628 1626 CCallHelpers::Label tierUpResume = jit.label(); 1629 1627 … … 1651 1649 } 1652 1650 1653 void AirIRGenerator::emitLoopTierUpCheck(int32_t incrementCount, const Stack& expressionStack, uint32_t loopIndex, uint32_t outerLoopIndex, B3::Origin origin) 1654 { 1655 UNUSED_PARAM(origin); 1651 void AirIRGenerator::emitLoopTierUpCheck(uint32_t loopIndex) 1652 { 1653 uint32_t outerLoopIndex = this->outerLoopIndex(); 1654 m_outerLoops.append(loopIndex); 1656 1655 1657 1656 if (!m_tierUp) … … 1681 1680 patchArgs.append(countdownPtr); 1682 1681 1683 Vector<B3::Type> types; 1684 for (auto& local : m_locals) { 1682 for (auto& local : m_locals) 1685 1683 patchArgs.append(ConstrainedTmp(local, B3::ValueRep::ColdAny)); 1686 types.append(toB3Type(local.type())); 1687 } 1688 for (auto& expression : expressionStack) { 1689 patchArgs.append(ConstrainedTmp(expression, B3::ValueRep::ColdAny)); 1690 types.append(toB3Type(expression.type())); 1684 for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) { 1685 ExpressionList& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack; 1686 for (auto& value : expressionStack) 1687 patchArgs.append(ConstrainedTmp(value, B3::ValueRep::ColdAny)); 1688 1689 const auto& results = m_parser->controlStack()[controlIndex].controlData.result; 1690 for (auto& value : results) 1691 patchArgs.append(ConstrainedTmp(value, B3::ValueRep::ColdAny)); 1691 1692 } 1692 1693 … … 1697 1698 AllowMacroScratchRegisterUsage allowScratch(jit); 1698 1699 CCallHelpers::Jump forceOSREntry = jit.branchTest8(CCallHelpers::NonZero, CCallHelpers::AbsoluteAddress(forceEntryTrigger)); 1699 CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32( incrementCount), CCallHelpers::Address(params[0].gpr()));1700 CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(TierUpCount::loopIncrement()), CCallHelpers::Address(params[0].gpr())); 1700 1701 MacroAssembler::Label tierUpResume = jit.label(); 1701 1702 1702 1703 OSREntryData& osrEntryData = m_tierUp->addOSREntryData(m_functionIndex, loopIndex); 1703 for (unsigned index = 0; index < types.size(); ++index) 1704 osrEntryData.values().constructAndAppend(params[index + 1], types[index]); 1704 // First argument is the countdown location. 1705 for (unsigned index = 1; index < params.value()->numChildren(); ++index) 1706 osrEntryData.values().constructAndAppend(params[index], params.value()->child(index)->type()); 1705 1707 OSREntryData* osrEntryDataPtr = &osrEntryData; 1706 1708 … … 1719 1721 } 1720 1722 1721 AirIRGenerator::ControlData AirIRGenerator::addLoop(Type signature, const Stack& expressionStack, uint32_t loopIndex)1723 AirIRGenerator::ControlData AirIRGenerator::addLoop(Type signature, const Stack&, uint32_t loopIndex) 1722 1724 { 1723 1725 BasicBlock* body = m_code.addBlock(); … … 1727 1729 m_currentBlock->setSuccessors(body); 1728 1730 1729 uint32_t outerLoopIndex = this->outerLoopIndex();1730 m_outerLoops.append(loopIndex);1731 1731 m_currentBlock = body; 1732 emitLoopTierUpCheck( TierUpCount::loopIncrement(), expressionStack, loopIndex, outerLoopIndex, origin());1732 emitLoopTierUpCheck(loopIndex); 1733 1733 1734 1734 return ControlData(origin(), signature, tmpForType(signature), BlockType::Loop, continuation, body); -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r249221 r249661 162 162 typedef Vector<ExpressionType, 1> ExpressionList; 163 163 164 friend class Stack; 165 class Stack { 166 public: 167 Stack(B3IRGenerator* generator) 168 : m_generator(generator) 169 { 170 } 171 172 void append(ExpressionType expression) 173 { 174 if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) { 175 Variable* variable = m_generator->m_proc.addVariable(expression->type()); 176 m_generator->m_currentBlock->appendNew<VariableValue>(m_generator->m_proc, Set, m_generator->origin(), variable, expression); 177 m_stack.append(variable); 178 return; 179 } 180 m_data.append(expression); 181 } 182 183 ExpressionType takeLast() 184 { 185 if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) 186 return m_generator->m_currentBlock->appendNew<VariableValue>(m_generator->m_proc, B3::Get, m_generator->origin(), m_stack.takeLast()); 187 return m_data.takeLast(); 188 } 189 190 ExpressionType last() 191 { 192 if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) 193 return m_generator->m_currentBlock->appendNew<VariableValue>(m_generator->m_proc, B3::Get, m_generator->origin(), m_stack.last()); 194 return m_data.last(); 195 } 196 197 unsigned size() const 198 { 199 if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) 200 return m_stack.size(); 201 return m_data.size(); 202 } 203 bool isEmpty() const { return size() == 0; } 204 205 ExpressionList convertToExpressionList() 206 { 207 if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) { 208 ExpressionList results; 209 for (unsigned i = 0; i < m_stack.size(); ++i) 210 results.append(at(i)); 211 return results; 212 } 213 return m_data; 214 } 215 216 ExpressionType at(unsigned i) const 217 { 218 if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) 219 return m_generator->m_currentBlock->appendNew<VariableValue>(m_generator->m_proc, B3::Get, m_generator->origin(), m_stack.at(i)); 220 return m_data.at(i); 221 } 222 223 Variable* variableAt(unsigned i) const 224 { 225 if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) 226 return m_stack.at(i); 227 return nullptr; 228 } 229 230 void shrink(unsigned i) 231 { 232 if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) { 233 m_stack.shrink(i); 234 return; 235 } 236 m_data.shrink(i); 237 } 238 239 void swap(Stack& stack) 240 { 241 std::swap(m_generator, stack.m_generator); 242 m_data.swap(stack.m_data); 243 m_stack.swap(stack.m_stack); 244 } 245 246 void dump() const 247 { 248 CommaPrinter comma(", ", ""); 249 dataLog(comma, "ExpressionStack:"); 250 if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) { 251 for (const auto& variable : m_stack) 252 dataLog(comma, *variable); 253 return; 254 } 255 for (const auto& expression : m_data) 256 dataLog(comma, *expression); 257 } 258 259 private: 260 B3IRGenerator* m_generator { nullptr }; 261 ExpressionList m_data; 262 Vector<Variable*> m_stack; 263 }; 264 Stack createStack() { return Stack(this); } 164 using Stack = ExpressionList; 165 Stack createStack() { return { }; } 265 166 266 167 using ControlType = ControlData; … … 352 253 void emitExceptionCheck(CCallHelpers&, ExceptionType); 353 254 354 void emitEntryTierUpCheck( int32_t incrementCount, B3::Origin);355 void emitLoopTierUpCheck( int32_t incrementCount, const Stack&, uint32_t, uint32_t, B3::Origin);255 void emitEntryTierUpCheck(); 256 void emitLoopTierUpCheck(uint32_t loopIndex); 356 257 357 258 void emitWriteBarrierForJSWrapper(); … … 585 486 } 586 487 587 emitEntryTierUpCheck( TierUpCount::functionEntryIncrement(), Origin());488 emitEntryTierUpCheck(); 588 489 589 490 if (m_compilationMode == CompilationMode::OMGForOSREntryMode) … … 1188 1089 B3IRGenerator::ExpressionType B3IRGenerator::addConstant(Type type, uint64_t value) 1189 1090 { 1091 1190 1092 return constant(toB3Type(type), value); 1191 1093 } 1192 1094 1193 void B3IRGenerator::emitEntryTierUpCheck( int32_t incrementCount, Origin origin)1095 void B3IRGenerator::emitEntryTierUpCheck() 1194 1096 { 1195 1097 if (!m_tierUp) … … 1197 1099 1198 1100 ASSERT(m_tierUp); 1199 Value* countDownLocation = constant(pointerType(), reinterpret_cast<uint64_t>(&m_tierUp->m_counter), origin);1200 1201 PatchpointValue* patch = m_currentBlock->appendNew<PatchpointValue>(m_proc, B3::Void, origin);1101 Value* countDownLocation = constant(pointerType(), reinterpret_cast<uint64_t>(&m_tierUp->m_counter), Origin()); 1102 1103 PatchpointValue* patch = m_currentBlock->appendNew<PatchpointValue>(m_proc, B3::Void, Origin()); 1202 1104 Effects effects = Effects::none(); 1203 1105 // FIXME: we should have a more precise heap range for the tier up count. … … 1210 1112 patch->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) { 1211 1113 AllowMacroScratchRegisterUsage allowScratch(jit); 1212 CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32( incrementCount), CCallHelpers::Address(params[0].gpr()));1114 CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(TierUpCount::functionEntryIncrement()), CCallHelpers::Address(params[0].gpr())); 1213 1115 CCallHelpers::Label tierUpResume = jit.label(); 1214 1116 … … 1234 1136 } 1235 1137 1236 void B3IRGenerator::emitLoopTierUpCheck(int32_t incrementCount, const Stack& expressionStack, uint32_t loopIndex, uint32_t outerLoopIndex, B3::Origin origin) 1237 { 1138 void B3IRGenerator::emitLoopTierUpCheck(uint32_t loopIndex) 1139 { 1140 uint32_t outerLoopIndex = this->outerLoopIndex(); 1141 m_outerLoops.append(loopIndex); 1142 1238 1143 if (!m_tierUp) 1239 1144 return; 1240 1145 1241 ASSERT(m_tierUp); 1242 1146 Origin origin = this->origin(); 1243 1147 ASSERT(m_tierUp->osrEntryTriggers().size() == loopIndex); 1244 1148 m_tierUp->osrEntryTriggers().append(TierUpCount::TriggerReason::DontTrigger); … … 1248 1152 1249 1153 Vector<ExpressionType> stackmap; 1250 Vector<B3::Type> types;1251 1154 for (auto& local : m_locals) { 1252 1155 ExpressionType result = m_currentBlock->appendNew<VariableValue>(m_proc, B3::Get, origin, local); 1253 1156 stackmap.append(result); 1254 types.append(result->type()); 1255 } 1256 for (unsigned i = 0; i < expressionStack.size(); ++i) { 1257 ExpressionType result = expressionStack.at(i); 1258 stackmap.append(result); 1259 types.append(result->type()); 1157 } 1158 for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) { 1159 auto& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack; 1160 for (Value* value : expressionStack) 1161 stackmap.append(value); 1260 1162 } 1261 1163 … … 1282 1184 AllowMacroScratchRegisterUsage allowScratch(jit); 1283 1185 CCallHelpers::Jump forceOSREntry = jit.branchTest8(CCallHelpers::NonZero, CCallHelpers::AbsoluteAddress(forceEntryTrigger)); 1284 CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32( incrementCount), CCallHelpers::Address(params[0].gpr()));1186 CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(TierUpCount::loopIncrement()), CCallHelpers::Address(params[0].gpr())); 1285 1187 MacroAssembler::Label tierUpResume = jit.label(); 1286 1188 1287 1189 OSREntryData& osrEntryData = m_tierUp->addOSREntryData(m_functionIndex, loopIndex); 1288 for (unsigned index = 0; index < types.size(); ++index) 1289 osrEntryData.values().constructAndAppend(params[index + 1], types[index]); 1190 // First argument is the countdown location. 1191 for (unsigned i = 1; i < params.value()->numChildren(); ++i) 1192 osrEntryData.values().constructAndAppend(params[i], params.value()->child(i)->type()); 1290 1193 OSREntryData* osrEntryDataPtr = &osrEntryData; 1291 1194 … … 1302 1205 } 1303 1206 1304 B3IRGenerator::ControlData B3IRGenerator::addLoop(Type signature, const Stack& stack, uint32_t loopIndex)1207 B3IRGenerator::ControlData B3IRGenerator::addLoop(Type signature, const Stack&, uint32_t loopIndex) 1305 1208 { 1306 1209 BasicBlock* body = m_proc.addBlock(); … … 1309 1212 m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), body); 1310 1213 if (loopIndex == m_loopIndexForOSREntry) { 1214 dataLogLnIf(WasmB3IRGeneratorInternal::verbose, "Setting up for OSR entry"); 1311 1215 m_currentBlock = m_rootBlock; 1312 m_osrEntryScratchBufferSize = m_locals.size() + stack.size();1313 1216 Value* pointer = m_rootBlock->appendNew<ArgumentRegValue>(m_proc, Origin(), GPRInfo::argumentGPR0); 1314 1217 1315 auto loadFromScratchBuffer = [&] (B3::Type type, unsigned index) { 1316 size_t offset = sizeof(uint64_t) * index; 1317 switch (type.kind()) { 1318 case B3::Int32: 1319 return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(), pointer, offset); 1320 case B3::Int64: 1321 return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, B3::Int64, origin(), pointer, offset); 1322 case B3::Float: 1323 return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, B3::Float, origin(), pointer, offset); 1324 case B3::Double: 1325 return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, B3::Double, origin(), pointer, offset); 1326 default: 1327 RELEASE_ASSERT_NOT_REACHED(); 1328 break; 1218 unsigned indexInBuffer = 0; 1219 auto loadFromScratchBuffer = [&] (B3::Type type) { 1220 size_t offset = sizeof(uint64_t) * indexInBuffer++; 1221 RELEASE_ASSERT(type.isNumeric()); 1222 return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, type, origin(), pointer, offset); 1223 }; 1224 1225 for (auto& local : m_locals) 1226 m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), local, loadFromScratchBuffer(local->type())); 1227 1228 for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) { 1229 const auto& data = m_parser->controlStack()[controlIndex].controlData; 1230 auto& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack; 1231 1232 // For each stack entry enclosed by this loop we need to replace the value with a phi so we can fill it on OSR entry. 1233 BasicBlock* sourceBlock = nullptr; 1234 unsigned blockIndex = 0; 1235 B3::InsertionSet insertionSet(m_proc); 1236 for (unsigned i = 0; i < expressionStack.size(); i++) { 1237 auto* value = expressionStack[i]; 1238 if (value->isConstant()) 1239 continue; 1240 1241 if (value->owner != sourceBlock) { 1242 insertionSet.execute(sourceBlock); 1243 ASSERT(insertionSet.isEmpty()); 1244 dataLogLnIf(WasmB3IRGeneratorInternal::verbose && sourceBlock, "Executed insertion set into: ", *sourceBlock); 1245 blockIndex = 0; 1246 sourceBlock = value->owner; 1247 } 1248 1249 while (sourceBlock->at(blockIndex++) != value) 1250 ASSERT(blockIndex < sourceBlock->size()); 1251 ASSERT(sourceBlock->at(blockIndex - 1) == value); 1252 1253 auto* phi = data.continuation->appendNew<Value>(m_proc, Phi, value->type(), value->origin()); 1254 expressionStack[i] = phi; 1255 m_currentBlock->appendNew<UpsilonValue>(m_proc, value->origin(), loadFromScratchBuffer(value->type()), phi); 1256 1257 auto* sourceUpsilon = m_proc.add<UpsilonValue>(value->origin(), value, phi); 1258 insertionSet.insertValue(blockIndex, sourceUpsilon); 1329 1259 } 1330 }; 1331 1332 unsigned indexInBuffer = 0; 1333 for (auto& local : m_locals) 1334 m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), local, loadFromScratchBuffer(local->type(), indexInBuffer++)); 1335 for (unsigned i = 0; i < stack.size(); ++i) { 1336 auto* variable = stack.variableAt(i); 1337 m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), variable, loadFromScratchBuffer(variable->type(), indexInBuffer++)); 1260 insertionSet.execute(sourceBlock); 1338 1261 } 1262 1263 m_osrEntryScratchBufferSize = indexInBuffer; 1339 1264 m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), body); 1340 1265 body->addPredecessor(m_currentBlock); 1341 1266 } 1342 1267 1343 uint32_t outerLoopIndex = this->outerLoopIndex();1344 m_outerLoops.append(loopIndex);1345 1268 m_currentBlock = body; 1346 emitLoopTierUpCheck( TierUpCount::loopIncrement(), stack, loopIndex, outerLoopIndex, origin());1269 emitLoopTierUpCheck(loopIndex); 1347 1270 1348 1271 return ControlData(m_proc, origin(), signature, BlockType::Loop, continuation, body); … … 1468 1391 // TopLevel does not have any code after this so we need to make sure we emit a return here. 1469 1392 if (data.type() == BlockType::TopLevel) 1470 return addReturn(entry.controlData, entry.enclosedExpressionStack .convertToExpressionList());1393 return addReturn(entry.controlData, entry.enclosedExpressionStack); 1471 1394 1472 1395 return { }; … … 1740 1663 } 1741 1664 1665 static void dumpExpressionStack(const CommaPrinter& comma, const B3IRGenerator::ExpressionList& expressionStack) 1666 { 1667 dataLog(comma, "ExpressionStack:"); 1668 for (const auto& expression : expressionStack) 1669 dataLog(comma, *expression); 1670 } 1671 1742 1672 void B3IRGenerator::dump(const Vector<ControlEntry>& controlStack, const Stack* expressionStack) 1743 1673 { … … 1753 1683 for (size_t i = controlStack.size(); i--;) { 1754 1684 dataLog(" ", controlStack[i].controlData, ": "); 1755 expressionStack->dump(); 1685 CommaPrinter comma(", ", ""); 1686 dumpExpressionStack(comma, *expressionStack); 1756 1687 expressionStack = &controlStack[i].enclosedExpressionStack; 1757 1688 dataLogLn(); -
trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h
r248989 r249661 61 61 size_t currentOpcodeStartingOffset() const { return m_currentOpcodeStartingOffset; } 62 62 63 Vector<ControlEntry>& controlStack() { return m_controlStack; } 64 63 65 private: 64 66 static const bool verbose = false; -
trunk/Source/JavaScriptCore/wasm/WasmOpcodeOrigin.cpp
r214544 r249661 33 33 void OpcodeOrigin::dump(PrintStream& out) const 34 34 { 35 out.print("{opcode: ", makeString(opcode()), ", location: ", location(), "}");35 out.print("{opcode: ", makeString(opcode()), ", location: ", RawPointer(reinterpret_cast<void*>(location())), "}"); 36 36 } 37 37 -
trunk/Tools/ChangeLog
r249653 r249661 1 2019-09-07 Keith Miller <keith_miller@apple.com> 2 3 OSR entry into wasm misses some contexts 4 https://bugs.webkit.org/show_bug.cgi?id=201569 5 6 Reviewed by Yusuke Suzuki. 7 8 Add new test harness mode for tests created from wast files. 9 10 * Scripts/run-jsc-stress-tests: 11 1 12 2019-09-09 Daniel Bates <dabates@apple.com> 2 13 -
trunk/Tools/Scripts/run-jsc-stress-tests
r249116 r249661 1115 1115 end 1116 1116 1117 def runHarnessTest(kind, *options) 1118 wasmFiles = allWasmFiles($collection) 1119 wasmFiles.each { 1120 | file | 1121 basename = file.basename.to_s 1122 addRunCommand("(" + basename + ")-" + kind, [pathToVM.to_s] + $testSpecificRequiredOptions + options + [$benchmark.to_s, "--", basename], silentOutputHandler, simpleErrorHandler) 1123 } 1124 end 1125 1126 def runWebAssemblyWithHarness(*optionalTestSpecificOptions) 1127 raise unless $benchmark.to_s =~ /harness\.m?js/ 1128 return if !$jitTests 1129 return if !$isFTLPlatform 1130 1131 wasmFiles = allWasmFiles($collection) 1132 prepareExtraRelativeFiles(wasmFiles.map { |f| f.basename }, $collection) 1133 1134 runHarnessTest("default-wasm", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1135 if $mode != "quick" 1136 runHarnessTest("wasm-no-cjit-yes-tls-context", "--useFastTLSForWasmContext=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + optionalTestSpecificOptions)) 1137 runHarnessTest("wasm-eager", *(FTL_OPTIONS + EAGER_OPTIONS + optionalTestSpecificOptions)) 1138 runHarnessTest("wasm-eager-jettison", "--forceCodeBlockToJettisonDueToOldAge=true", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1139 runHarnessTest("wasm-no-call-ic", "--useCallICsForWebAssemblyToJSCalls=false", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1140 runHarnessTest("wasm-no-tls-context", "--useFastTLSForWasmContext=false", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1141 runHarnessTest("wasm-slow-memory", "--useWebAssemblyFastMemory=false", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1142 runHarnessTest("wasm-no-air", "--wasmBBQUsesAir=false", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1143 runHarnessTest("wasm-collect-continuously", "--collectContinuously=true", *(FTL_OPTIONS + optionalTestSpecificOptions)) if shouldCollectContinuously? 1144 end 1145 end 1146 1117 1147 def runWebAssemblyEmscripten(mode) 1118 1148 case mode … … 1482 1512 $skipped = true 1483 1513 puts "Skipping #{$collectionName}/#{$benchmark}" 1514 end 1515 1516 def allWasmFiles(path) 1517 if path.file? 1518 [path] 1519 else 1520 result = [] 1521 Dir.foreach(path) { 1522 | filename | 1523 next unless filename =~ /\.m?wasm$/ 1524 next unless (path + filename).file? 1525 result << path + filename 1526 } 1527 result 1528 end 1484 1529 end 1485 1530
Note: See TracChangeset
for help on using the changeset viewer.