Changeset 237242 in webkit
- Timestamp:
- Oct 17, 2018 6:14:00 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r237200 r237242 1 2018-10-17 Caio Lima <ticaiolima@gmail.com> 2 3 [BigInt] Add ValueSub into DFG 4 https://bugs.webkit.org/show_bug.cgi?id=186176 5 6 Reviewed by Yusuke Suzuki. 7 8 * stress/big-int-subtraction-jit.js: 9 * stress/value-sub-big-int-prediction-propagation.js: Added. 10 * stress/value-sub-big-int-untyped.js: Added. 11 1 12 2018-10-16 Dominik Infuehr <dinfuehr@igalia.com> 2 13 -
trunk/JSTests/stress/big-int-subtraction-jit.js
r232449 r237242 9 9 10 10 function bigIntAddition(x, y) { 11 return x - y ;11 return x - y - 1n; 12 12 } 13 13 noInline(bigIntAddition); … … 15 15 for (let i = 0; i < 10000; i++) { 16 16 let r = bigIntAddition(3n, 10n); 17 assert.sameValue(r, - 7n, 3n + " - " + 10n + "= " + r);17 assert.sameValue(r, -8n, 3n + " - " + 10n + " - 1 = " + r); 18 18 } 19 19 -
trunk/Source/JavaScriptCore/ChangeLog
r237241 r237242 1 2018-10-17 Caio Lima <ticaiolima@gmail.com> 2 3 [BigInt] Add ValueSub into DFG 4 https://bugs.webkit.org/show_bug.cgi?id=186176 5 6 Reviewed by Yusuke Suzuki. 7 8 We are introducing in this patch a new node called ValueSub. This node 9 is necessary due to introduction of BigInt, making subtraction 10 operations result in non-Number values in some cases. In such case, ValueSub is 11 responsible to handle Untyped and BigInt operations. 12 In addition, we are also creating a speculative path when both 13 operands are BigInt. According to a simple BigInt subtraction microbenchmark, 14 this represents a speedup of ~1.2x faster. 15 16 big-int-simple-sub 14.6427+-0.5652 ^ 11.9559+-0.6485 ^ definitely 1.2247x faster 17 18 * dfg/DFGAbstractInterpreterInlines.h: 19 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 20 * dfg/DFGByteCodeParser.cpp: 21 (JSC::DFG::ByteCodeParser::parseBlock): 22 * dfg/DFGClobberize.h: 23 (JSC::DFG::clobberize): 24 * dfg/DFGDoesGC.cpp: 25 (JSC::DFG::doesGC): 26 * dfg/DFGFixupPhase.cpp: 27 (JSC::DFG::FixupPhase::fixupNode): 28 * dfg/DFGGraph.h: 29 (JSC::DFG::Graph::addSpeculationMode): 30 * dfg/DFGNodeType.h: 31 * dfg/DFGOperations.cpp: 32 * dfg/DFGOperations.h: 33 * dfg/DFGPredictionPropagationPhase.cpp: 34 * dfg/DFGSafeToExecute.h: 35 (JSC::DFG::safeToExecute): 36 * dfg/DFGSpeculativeJIT.cpp: 37 (JSC::DFG::SpeculativeJIT::compileValueSub): 38 (JSC::DFG::SpeculativeJIT::compileArithSub): 39 * dfg/DFGSpeculativeJIT.h: 40 * dfg/DFGSpeculativeJIT32_64.cpp: 41 (JSC::DFG::SpeculativeJIT::compile): 42 * dfg/DFGSpeculativeJIT64.cpp: 43 (JSC::DFG::SpeculativeJIT::compile): 44 * dfg/DFGValidate.cpp: 45 * ftl/FTLCapabilities.cpp: 46 (JSC::FTL::canCompile): 47 * ftl/FTLLowerDFGToB3.cpp: 48 (JSC::FTL::DFG::LowerDFGToB3::compileNode): 49 (JSC::FTL::DFG::LowerDFGToB3::compileValueAdd): 50 (JSC::FTL::DFG::LowerDFGToB3::compileValueSub): 51 1 52 2018-10-17 Mark Lam <mark.lam@apple.com> 2 53 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r236901 r237242 590 590 break; 591 591 } 592 592 593 case ValueSub: 593 594 case ValueAdd: { 594 ASSERT(node->binaryUseKind() == UntypedUse);595 DFG_ASSERT(m_graph, node, node->binaryUseKind() == UntypedUse || node->binaryUseKind() == BigIntUse); 595 596 clobberWorld(); 596 setTypeForNode(node, SpecString | SpecBytecodeNumber); 597 if (node->binaryUseKind() == BigIntUse) 598 setTypeForNode(node, SpecBigInt); 599 else 600 setTypeForNode(node, SpecString | SpecBytecodeNumber | SpecBigInt); 597 601 break; 598 602 } -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r236901 r237242 4934 4934 Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand)); 4935 4935 Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand)); 4936 set(VirtualRegister(currentInstruction[1].u.operand), makeSafe(addToGraph(ArithSub, op1, op2))); 4936 if (op1->hasNumberResult() && op2->hasNumberResult()) 4937 set(VirtualRegister(currentInstruction[1].u.operand), makeSafe(addToGraph(ArithSub, op1, op2))); 4938 else 4939 set(VirtualRegister(currentInstruction[1].u.operand), makeSafe(addToGraph(ValueSub, op1, op2))); 4937 4940 NEXT_OPCODE(op_sub); 4938 4941 } -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r236901 r237242 640 640 case ValueNegate: 641 641 case ValueAdd: 642 case ValueSub: 642 643 case SetFunctionName: 643 644 case GetDynamicVar: -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r237215 r237242 100 100 case ValueBitOr: 101 101 case ValueAdd: 102 case ValueSub: 102 103 case ValueNegate: 103 104 case TryGetById: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r236901 r237242 99 99 return; 100 100 } 101 101 102 case ValueSub: { 103 Edge& child1 = node->child1(); 104 Edge& child2 = node->child2(); 105 106 if (Node::shouldSpeculateBigInt(child1.node(), child2.node())) { 107 fixEdge<BigIntUse>(child1); 108 fixEdge<BigIntUse>(child2); 109 break; 110 } 111 112 if (Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) { 113 fixEdge<UntypedUse>(child1); 114 fixEdge<UntypedUse>(child2); 115 break; 116 } 117 118 if (attemptToMakeIntegerAdd(node)) { 119 // FIXME: [DFG] Clear ArithSub when ArithMode is Unchecked 120 // https://bugs.webkit.org/show_bug.cgi?id=190607 121 node->setOp(ArithSub); 122 break; 123 } 124 125 DFG_ASSERT(m_graph, node, Node::shouldSpeculateNumberOrBooleanExpectingDefined(child1.node(), child2.node())); 126 fixDoubleOrBooleanEdge(node->child1()); 127 fixDoubleOrBooleanEdge(node->child2()); 128 node->setOp(ArithSub); 129 node->setResult(NodeResultDouble); 130 131 break; 132 } 133 102 134 case ValueBitOr: 103 135 case ValueBitAnd: { … … 294 326 case ArithAdd: 295 327 case ArithSub: { 296 if (op == ArithSub 297 && Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) { 298 fixEdge<UntypedUse>(node->child1()); 299 fixEdge<UntypedUse>(node->child2()); 300 node->setResult(NodeResultJS); 301 break; 302 } 328 // FIXME: [DFG] Clear ArithSub when ArithMode is Unchecked 329 // https://bugs.webkit.org/show_bug.cgi?id=190607 303 330 if (attemptToMakeIntegerAdd(node)) 304 331 break; -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r234178 r237242 239 239 AddSpeculationMode addSpeculationMode(Node* add, bool leftShouldSpeculateInt32, bool rightShouldSpeculateInt32, PredictionPass pass) 240 240 { 241 ASSERT(add->op() == ValueAdd || add->op() == ArithAdd || add->op() == ArithSub);241 ASSERT(add->op() == ValueAdd || add->op() == ValueSub || add->op() == ArithAdd || add->op() == ArithSub); 242 242 243 243 RareCaseProfilingSource source = add->sourceFor(pass); -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r236901 r237242 171 171 /* Add of values may either be arithmetic, or result in string concatenation. */\ 172 172 macro(ValueAdd, NodeResultJS | NodeMustGenerate) \ 173 \ 174 macro(ValueSub, NodeResultJS | NodeMustGenerate) \ 173 175 \ 174 176 /* Add of values that always convers its inputs to strings. May have two or three kids. */\ -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r236901 r237242 1287 1287 } 1288 1288 1289 JSCell* JIT_OPERATION operationSubBigInt(ExecState* exec, JSCell* op1, JSCell* op2) 1290 { 1291 VM* vm = &exec->vm(); 1292 NativeCallFrameTracer tracer(vm, exec); 1293 1294 JSBigInt* leftOperand = jsCast<JSBigInt*>(op1); 1295 JSBigInt* rightOperand = jsCast<JSBigInt*>(op2); 1296 1297 return JSBigInt::sub(*vm, leftOperand, rightOperand); 1298 } 1299 1289 1300 JSCell* JIT_OPERATION operationBitAndBigInt(ExecState* exec, JSCell* op1, JSCell* op2) 1290 1301 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r236901 r237242 164 164 size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL; 165 165 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; 166 JSCell* JIT_OPERATION operationSubBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; 166 167 JSCell* JIT_OPERATION operationBitAndBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; 167 168 JSCell* JIT_OPERATION operationBitOrBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r236901 r237242 244 244 changed |= mergePrediction(SpecInt32Only); 245 245 } 246 break; 247 } 248 249 case ValueSub: { 250 SpeculatedType left = node->child1()->prediction(); 251 SpeculatedType right = node->child2()->prediction(); 252 253 if (left && right) { 254 if (isFullNumberOrBooleanSpeculationExpectingDefined(left) 255 && isFullNumberOrBooleanSpeculationExpectingDefined(right)) { 256 if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32) 257 changed |= mergePrediction(SpecInt32Only); 258 else if (m_graph.addShouldSpeculateAnyInt(node)) 259 changed |= mergePrediction(SpecInt52Only); 260 else 261 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); 262 } else if (isBigIntSpeculation(left) && isBigIntSpeculation(right)) 263 changed |= mergePrediction(SpecBigInt); 264 else { 265 changed |= mergePrediction(SpecInt32Only); 266 if (node->mayHaveDoubleResult()) 267 changed |= mergePrediction(SpecBytecodeDouble); 268 if (node->mayHaveNonNumberResult()) 269 changed |= mergePrediction(SpecBigInt); 270 } 271 } 272 246 273 break; 247 274 } … … 522 549 switch (node->op()) { 523 550 case ValueAdd: 551 case ValueSub: 524 552 case ArithAdd: 525 553 case ArithSub: { … … 1069 1097 case ValueNegate: 1070 1098 case ValueAdd: 1099 case ValueSub: 1071 1100 case ArithAdd: 1072 1101 case ArithSub: -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r236901 r237242 231 231 case ValueNegate: 232 232 case ValueAdd: 233 case ValueSub: 233 234 case TryGetById: 234 235 case DeleteById: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r237136 r237242 3872 3872 } 3873 3873 3874 void SpeculativeJIT::compileValueSub(Node* node) 3875 { 3876 Edge& leftChild = node->child1(); 3877 Edge& rightChild = node->child2(); 3878 3879 if (node->binaryUseKind() == UntypedUse) { 3880 #if USE(JSVALUE64) 3881 bool needsScratchGPRReg = true; 3882 bool needsScratchFPRReg = false; 3883 #else 3884 bool needsScratchGPRReg = true; 3885 bool needsScratchFPRReg = true; 3886 #endif 3887 3888 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 3889 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex); 3890 Instruction* instruction = &baselineCodeBlock->instructions()[node->origin.semantic.bytecodeIndex]; 3891 JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC(arithProfile, instruction); 3892 auto repatchingFunction = operationValueSubOptimize; 3893 auto nonRepatchingFunction = operationValueSub; 3894 3895 compileMathIC(node, subIC, needsScratchGPRReg, needsScratchFPRReg, repatchingFunction, nonRepatchingFunction); 3896 return; 3897 } 3898 3899 ASSERT(leftChild.useKind() == BigIntUse && rightChild.useKind() == BigIntUse); 3900 3901 SpeculateCellOperand left(this, node->child1()); 3902 SpeculateCellOperand right(this, node->child2()); 3903 GPRReg leftGPR = left.gpr(); 3904 GPRReg rightGPR = right.gpr(); 3905 3906 speculateBigInt(leftChild, leftGPR); 3907 speculateBigInt(rightChild, rightGPR); 3908 3909 flushRegisters(); 3910 GPRFlushedCallResult result(this); 3911 GPRReg resultGPR = result.gpr(); 3912 3913 callOperation(operationSubBigInt, resultGPR, leftGPR, rightGPR); 3914 3915 m_jit.exceptionCheck(); 3916 cellResult(resultGPR, node); 3917 } 3918 3874 3919 template <typename Generator, typename RepatchingFunction, typename NonRepatchingFunction> 3875 3920 void SpeculativeJIT::compileMathIC(Node* node, JITBinaryMathIC<Generator>* mathIC, bool needsScratchGPRReg, bool needsScratchFPRReg, RepatchingFunction repatchingFunction, NonRepatchingFunction nonRepatchingFunction) … … 4504 4549 4505 4550 doubleResult(result.fpr(), node); 4506 return;4507 }4508 4509 case UntypedUse: {4510 #if USE(JSVALUE64)4511 bool needsScratchGPRReg = true;4512 bool needsScratchFPRReg = false;4513 #else4514 bool needsScratchGPRReg = true;4515 bool needsScratchFPRReg = true;4516 #endif4517 4518 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);4519 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);4520 Instruction* instruction = &baselineCodeBlock->instructions()[node->origin.semantic.bytecodeIndex];4521 JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC(arithProfile, instruction);4522 auto repatchingFunction = operationValueSubOptimize;4523 auto nonRepatchingFunction = operationValueSub;4524 4525 compileMathIC(node, subIC, needsScratchGPRReg, needsScratchFPRReg, repatchingFunction, nonRepatchingFunction);4526 4551 return; 4527 4552 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r236901 r237242 1345 1345 void compileArithDoubleUnaryOp(Node*, double (*doubleFunction)(double), double (*operation)(ExecState*, EncodedJSValue)); 1346 1346 void compileValueAdd(Node*); 1347 void compileValueSub(Node*); 1347 1348 void compileArithAdd(Node*); 1348 1349 void compileMakeRope(Node*); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r236901 r237242 2028 2028 case ValueAdd: 2029 2029 compileValueAdd(node); 2030 break; 2031 2032 case ValueSub: 2033 compileValueSub(node); 2030 2034 break; 2031 2035 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r237173 r237242 2170 2170 case ValueAdd: 2171 2171 compileValueAdd(node); 2172 break; 2173 2174 case ValueSub: 2175 compileValueSub(node); 2172 2176 break; 2173 2177 -
trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp
r234082 r237242 255 255 case MakeRope: 256 256 case ValueAdd: 257 case ValueSub: 257 258 case ArithAdd: 258 259 case ArithSub: -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r236901 r237242 91 91 case ValueNegate: 92 92 case ValueAdd: 93 case ValueSub: 93 94 case StrCat: 94 95 case ArithAdd: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r237173 r237242 594 594 compileValueAdd(); 595 595 break; 596 case ValueSub: 597 compileValueSub(); 598 break; 596 599 case StrCat: 597 600 compileStrCat(); … … 1864 1867 auto nonRepatchingFunction = operationValueAdd; 1865 1868 compileBinaryMathIC<JITAddGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction); 1869 } 1870 1871 void compileValueSub() 1872 { 1873 if (m_node->isBinaryUseKind(BigIntUse)) { 1874 LValue left = lowBigInt(m_node->child1()); 1875 LValue right = lowBigInt(m_node->child2()); 1876 1877 LValue result = vmCall(pointerType(), m_out.operation(operationSubBigInt), m_callFrame, left, right); 1878 setJSValue(result); 1879 return; 1880 } 1881 1882 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 1883 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex); 1884 Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex]; 1885 auto repatchingFunction = operationValueSubOptimize; 1886 auto nonRepatchingFunction = operationValueSub; 1887 compileBinaryMathIC<JITSubGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction); 1866 1888 } 1867 1889
Note: See TracChangeset
for help on using the changeset viewer.