Changeset 278568 in webkit
- Timestamp:
- Jun 7, 2021, 12:55:30 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 14 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/microbenchmarks/poly-stricteq-not-double-nor-string.js (added)
-
JSTests/microbenchmarks/poly-stricteq-not-double.js (added)
-
JSTests/microbenchmarks/poly-stricteq.js (modified) (2 diffs)
-
JSTests/stress/poly-stricteq-not-double-nor-string-fail.js (added)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/SpeculatedType.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGDoesGC.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGNode.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSafeToExecute.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (modified) (2 diffs)
-
Source/JavaScriptCore/dfg/DFGUseKind.cpp (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGUseKind.h (modified) (3 diffs)
-
Source/JavaScriptCore/ftl/FTLCapabilities.cpp (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r278510 r278568 1 2021-06-07 Robin Morisset <rmorisset@apple.com> 2 3 Optimize compareStrictEq when neither side is a double and at least one is neither a string nor a BigInt 4 https://bugs.webkit.org/show_bug.cgi?id=226676 5 6 Reviewed by Filip Pizlo. 7 8 I made two variants of the already existing poly-stricteq microbenchmarks with different types in the array. 9 I also tweaked all three so that we more reliably reach the FTL. 10 Finally I added a stress-test to verify that I did not introduce an OSR exit bug. 11 12 * microbenchmarks/poly-stricteq-not-double-nor-string.js: Added. 13 (foo): 14 (test): 15 * microbenchmarks/poly-stricteq-not-double.js: Added. 16 (foo): 17 (test): 18 * microbenchmarks/poly-stricteq.js: 19 (foo): 20 (test): 21 * stress/poly-stricteq-not-double-nor-string-fail.js: Added. 22 (foo): 23 (test): 24 1 25 2021-06-04 Yusuke Suzuki <ysuzuki@apple.com> 2 26 -
trunk/JSTests/microbenchmarks/poly-stricteq.js
r251463 r278568 7 7 8 8 for (var i = 0; i < 1000; ++i) { 9 array.push( i);10 array.push( (i%2) == 0);9 array.push((i % 2) == 0); 10 array.push(3.14 * i); 11 11 array.push("" + i); 12 12 var o = {}; … … 16 16 17 17 var numStrictEqual = 0; 18 for (var i = 0; i < array.length; ++i) { 19 for (var j = i + 1; j < array.length; ++j) { 20 if (array[i] === array[j]) 21 numStrictEqual++;22 }18 19 function foo(x, y) 20 { 21 if(x === y) 22 numStrictEqual++; 23 23 } 24 24 25 if (numStrictEqual != 249500) 26 throw "Incorrect result: " + numStrictEqual; 25 function test() 26 { 27 for (var i = 0; i < array.length; ++i) { 28 for (var j = i + 1; j < array.length; ++j) { 29 foo(array[i], array[j]); 30 } 31 } 32 33 if (numStrictEqual != 249500) 34 throw "Incorrect result: " + numStrictEqual; 35 } 36 noInline(test); 37 test(); 27 38 28 39 29 -
trunk/Source/JavaScriptCore/ChangeLog
r278553 r278568 1 2021-06-07 Robin Morisset <rmorisset@apple.com> 2 3 Optimize compareStrictEq when neither side is a double and at least one is neither a string nor a BigInt 4 https://bugs.webkit.org/show_bug.cgi?id=226676 5 6 Reviewed by Filip Pizlo. 7 8 There is exactly one case where x === y must return false despite x and y being JSValues with the same bits: 9 NaN === NaN 10 There are a few cases where x === y must return true despite x and y being JSValues with potentially different bits: 11 Double === Int32 12 String === String 13 HeapBigInt === HeapBigInt 14 HeapBigInt === BigInt32 (if they are enabled) 15 If we don't have a double on either side, at least one side has neither a String nor a HeapBigInt, and BigInt32 are disabled, we can clearly ignore all of these pathological cases. 16 17 This optimization was decided based on looking at DFG graphs of Speedometer2; here is a sample of the compareStrictEq(Untyped, Untyped), courtesy of Phil: 18 Final|Array|String|Bool, Final|Array|String|Bool 19 Array|String|Bool, String|Bool (twice) 20 Array|String|Bool, String|Int32 (once in DFG, once in FTL) 21 ! Array|String|Bool, Array|Bool 22 ! Final|Other, Final|Other 23 ! Int32|Other, Int32 24 Final|StringIdent, Final|StringIdent (3 times) 25 Final|StringIdent|BoolInt32, StringIdent|BoolInt32 (twice) 26 String|Bool, String|Bool (4 times) 27 DoublePureNaN, String|Bool 28 ! Other, Function|Other 29 ! Final|Other, Final|Function|Other (twice) 30 Final|String|Bool|Other, Final|String|Bool|Other (3 times, two in the FTL) 31 Final|String|Int32, String|Int32 (four times) 32 String|Int32|Bool, Function|String|Int32|Bool (twice) 33 String|DoublePureNaN, String|Bool (twice) 34 ! Final|Bool|Other, Final|Function|Other (four times, twice in FTL) 35 I marked with a ! those for which this optimization should apply. 36 37 The only slightly interesting part of this patch is DFG::SpeculativeJIT::speculateNeitherDoubleNorHeapBigIntNorString where I took care to skip every test whose result we can predict from the abstract interpreter. 38 39 Results on microbenchmarks: 40 poly-stricteq-not-double 45.5793+-0.5304 ? 46.0306+-0.5621 ? 41 poly-stricteq-not-double-nor-string 45.5829+-0.5750 ^ 16.9089+-0.3070 ^ definitely 2.6958x faster 42 poly-stricteq 49.9719+-0.6450 48.9855+-0.5227 might be 1.0201x faster 43 44 I also measured the amount of code that we generate in the DFG on JetStream2. 45 The results here are disappointing but still measurable. Before: 46 DFG_fast_CompareStrictEq totalBytes: 468425 count: 10951 avg: 42.774632 47 DFG_fast_CompareStrictEq totalBytes: 468020 count: 10917 avg: 42.870752 48 DFG_fast_CompareStrictEq totalBytes: 467424 count: 10888 avg: 42.930198 49 After: 50 DFG_fast_CompareStrictEq totalBytes: 463946 count: 10917 avg: 42.497573 51 DFG_fast_CompareStrictEq totalBytes: 474492 count: 11138 avg: 42.601185 52 DFG_fast_CompareStrictEq totalBytes: 467138 count: 10970 avg: 42.583227 53 54 * bytecode/SpeculatedType.h: 55 (JSC::isNeitherDoubleNorHeapBigIntNorStringSpeculation): 56 * dfg/DFGDoesGC.cpp: 57 (JSC::DFG::doesGC): 58 * dfg/DFGFixupPhase.cpp: 59 (JSC::DFG::FixupPhase::fixupCompareStrictEqAndSameValue): 60 * dfg/DFGNode.h: 61 (JSC::DFG::Node::shouldSpeculateNeitherDoubleNorHeapBigIntNorString): 62 * dfg/DFGSafeToExecute.h: 63 (JSC::DFG::SafeToExecuteEdge::operator()): 64 * dfg/DFGSpeculativeJIT.cpp: 65 (JSC::DFG::SpeculativeJIT::compileStrictEq): 66 (JSC::DFG::SpeculativeJIT::compileNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality): 67 (JSC::DFG::SpeculativeJIT::compilePeepHoleNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality): 68 (JSC::DFG::SpeculativeJIT::speculateNotDouble): 69 (JSC::DFG::SpeculativeJIT::speculateNeitherDoubleNorHeapBigIntNorString): 70 (JSC::DFG::SpeculativeJIT::speculate): 71 * dfg/DFGSpeculativeJIT.h: 72 * dfg/DFGUseKind.cpp: 73 (WTF::printInternal): 74 * dfg/DFGUseKind.h: 75 (JSC::DFG::typeFilterFor): 76 (JSC::DFG::checkMayCrashIfInputIsEmpty): 77 * ftl/FTLCapabilities.cpp: 78 (JSC::FTL::canCompile): 79 * ftl/FTLLowerDFGToB3.cpp: 80 (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): 81 (JSC::FTL::DFG::LowerDFGToB3::speculate): 82 (JSC::FTL::DFG::LowerDFGToB3::speculateNeitherDoubleNorHeapBigIntNorString): 83 1 84 2021-06-07 Tuomas Karkkainen <tuomas.webkit@apple.com> 2 85 -
trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h
r278465 r278568 445 445 } 446 446 447 inline bool isNeitherDoubleNorHeapBigIntNorStringSpeculation(SpeculatedType type) 448 { 449 return !(type & (SpecFullDouble | SpecHeapBigInt | SpecString)); 450 } 451 447 452 inline bool isOtherSpeculation(SpeculatedType value) 448 453 { -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r278462 r278568 48 48 // 2. Resolves a rope string, which allocates a string. 49 49 // 3. Produces a string (which allocates the string) except when we can prove that 50 // the string will always be one of the pre-all coated SmallStrings.50 // the string will always be one of the pre-allocated SmallStrings. 51 51 // 4. Triggers a structure transition (which can allocate a new structure) 52 52 // unless it is a known transition between previously allocated structures … … 497 497 || node->isBinaryUseKind(ObjectUse) 498 498 || node->isBinaryUseKind(MiscUse, UntypedUse) || node->isBinaryUseKind(UntypedUse, MiscUse) 499 || node->isBinaryUseKind(StringIdentUse, NotStringVarUse) || node->isBinaryUseKind(NotStringVarUse, StringIdentUse)) 499 || node->isBinaryUseKind(StringIdentUse, NotStringVarUse) || node->isBinaryUseKind(NotStringVarUse, StringIdentUse) 500 || node->isBinaryUseKind(NotDoubleUse, NeitherDoubleNorHeapBigIntNorStringUse) || node->isBinaryUseKind(NotDoubleUse, NeitherDoubleNorHeapBigIntNorStringUse)) 500 501 return false; 501 502 return true; -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r278465 r278568 4409 4409 return; 4410 4410 } 4411 #if !USE(BIGINT32) 4412 // As long as a BigInt32 and a HeapBigInt can compare equal, it is not sound to replace compareStrictEq by a simple comparison of the JSValue in the following cases. 4413 if (node->child1()->shouldSpeculateNeitherDoubleNorHeapBigIntNorString() 4414 && node->child2()->shouldSpeculateNotDouble()) { 4415 fixEdge<NeitherDoubleNorHeapBigIntNorStringUse>(node->child1()); 4416 fixEdge<NotDoubleUse>(node->child2()); 4417 node->setOpAndDefaultFlags(CompareStrictEq); 4418 return; 4419 } 4420 if (node->child1()->shouldSpeculateNotDouble() 4421 && node->child2()->shouldSpeculateNeitherDoubleNorHeapBigIntNorString()) { 4422 fixEdge<NotDoubleUse>(node->child1()); 4423 fixEdge<NeitherDoubleNorHeapBigIntNorStringUse>(node->child2()); 4424 node->setOpAndDefaultFlags(CompareStrictEq); 4425 return; 4426 } 4427 #endif 4411 4428 } 4412 4429 -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r278465 r278568 2803 2803 return isNotDoubleSpeculation(prediction()); 2804 2804 } 2805 2806 bool shouldSpeculateNeitherDoubleNorHeapBigIntNorString() 2807 { 2808 return isNeitherDoubleNorHeapBigIntNorStringSpeculation(prediction()); 2809 } 2805 2810 2806 2811 bool shouldSpeculateUntypedForArithmetic() -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r278465 r278568 94 94 case DoubleRepAnyIntUse: 95 95 case NotDoubleUse: 96 case NeitherDoubleNorHeapBigIntNorStringUse: 96 97 return; 97 98 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r278476 r278568 6934 6934 return false; 6935 6935 } 6936 6936 6937 #if !USE(BIGINT32) 6938 if (node->isBinaryUseKind(NotDoubleUse, NeitherDoubleNorHeapBigIntNorStringUse)) { 6939 Edge notDoubleChild = node->child1(); 6940 Edge neitherDoubleNorHeapBigIntNorStringChild = node->child2(); 6941 unsigned branchIndexInBlock = detectPeepHoleBranch(); 6942 if (branchIndexInBlock != UINT_MAX) { 6943 Node* branchNode = m_block->at(branchIndexInBlock); 6944 compilePeepHoleNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality(node, branchNode, notDoubleChild, neitherDoubleNorHeapBigIntNorStringChild); 6945 use(notDoubleChild); 6946 use(neitherDoubleNorHeapBigIntNorStringChild); 6947 m_indexInBlock = branchIndexInBlock; 6948 m_currentNode = branchNode; 6949 return true; 6950 } 6951 compileNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality(node, notDoubleChild, neitherDoubleNorHeapBigIntNorStringChild); 6952 return false; 6953 } 6954 if (node->isBinaryUseKind(NeitherDoubleNorHeapBigIntNorStringUse, NotDoubleUse)) { 6955 Edge neitherDoubleNorHeapBigIntNorStringChild = node->child1(); 6956 Edge notDoubleChild = node->child2(); 6957 unsigned branchIndexInBlock = detectPeepHoleBranch(); 6958 if (branchIndexInBlock != UINT_MAX) { 6959 Node* branchNode = m_block->at(branchIndexInBlock); 6960 compilePeepHoleNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality(node, branchNode, notDoubleChild, neitherDoubleNorHeapBigIntNorStringChild); 6961 use(notDoubleChild); 6962 use(neitherDoubleNorHeapBigIntNorStringChild); 6963 m_indexInBlock = branchIndexInBlock; 6964 m_currentNode = branchNode; 6965 return true; 6966 } 6967 compileNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality(node, notDoubleChild, neitherDoubleNorHeapBigIntNorStringChild); 6968 return false; 6969 } 6970 #endif 6971 6937 6972 if (node->isBinaryUseKind(HeapBigIntUse)) { 6938 6973 compileHeapBigIntEquality(node); … … 7162 7197 jump(notTaken); 7163 7198 } 7199 } 7200 7201 void SpeculativeJIT::compileNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality(Node* node, Edge notDoubleChild, Edge neitherDoubleNorHeapBigIntNorStringChild) 7202 { 7203 JSValueOperand left(this, notDoubleChild, ManualOperandSpeculation); 7204 JSValueOperand right(this, neitherDoubleNorHeapBigIntNorStringChild, ManualOperandSpeculation); 7205 7206 GPRTemporary temp(this); 7207 #if USE(JSVALUE64) 7208 GPRTemporary result(this, Reuse, left, right); 7209 #else 7210 GPRTemporary result(this, Reuse, left, PayloadWord); 7211 #endif 7212 JSValueRegs leftRegs = left.jsValueRegs(); 7213 JSValueRegs rightRegs = right.jsValueRegs(); 7214 GPRReg tempGPR = temp.gpr(); 7215 GPRReg resultGPR = result.gpr(); 7216 7217 speculateNotDouble(notDoubleChild, leftRegs, tempGPR); 7218 speculateNeitherDoubleNorHeapBigIntNorString(neitherDoubleNorHeapBigIntNorStringChild, rightRegs, tempGPR); 7219 7220 #if USE(JSVALUE64) 7221 m_jit.compare64(JITCompiler::Equal, left.gpr(), right.gpr(), result.gpr()); 7222 #else 7223 m_jit.move(TrustedImm32(0), result.gpr()); 7224 JITCompiler::Jump notEqual = m_jit.branch32(JITCompiler::NotEqual, left.tagGPR(), right.tagGPR()); 7225 m_jit.compare32(JITCompiler::Equal, left.payloadGPR(), right.payloadGPR(), result.gpr()); 7226 notEqual.link(&m_jit); 7227 #endif 7228 unblessedBooleanResult(resultGPR, node); 7229 } 7230 7231 void SpeculativeJIT::compilePeepHoleNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality(Node*, Node* branchNode, Edge notDoubleChild, Edge neitherDoubleNorHeapBigIntNorStringChild) 7232 { 7233 JSValueOperand left(this, notDoubleChild, ManualOperandSpeculation); 7234 JSValueOperand right(this, neitherDoubleNorHeapBigIntNorStringChild, ManualOperandSpeculation); 7235 7236 GPRTemporary temp(this); 7237 JSValueRegs leftRegs = left.jsValueRegs(); 7238 JSValueRegs rightRegs = right.jsValueRegs(); 7239 GPRReg tempGPR = temp.gpr(); 7240 7241 speculateNotDouble(notDoubleChild, leftRegs, tempGPR); 7242 speculateNeitherDoubleNorHeapBigIntNorString(neitherDoubleNorHeapBigIntNorStringChild, rightRegs, tempGPR); 7243 7244 BasicBlock* taken = branchNode->branchData()->taken.block; 7245 BasicBlock* notTaken = branchNode->branchData()->notTaken.block; 7246 7247 #if USE(JSVALUE64) 7248 if (taken == nextBlock()) { 7249 branch64(JITCompiler::NotEqual, left.gpr(), right.gpr(), notTaken); 7250 jump(taken); 7251 } else { 7252 branch64(JITCompiler::Equal, left.gpr(), right.gpr(), taken); 7253 jump(notTaken); 7254 } 7255 #else 7256 branch32(JITCompiler::NotEqual, left.tagGPR(), right.tagGPR(), notTaken); 7257 if (taken == nextBlock()) { 7258 branch32(JITCompiler::NotEqual, left.payloadGPR(), right.payloadGPR(), notTaken); 7259 jump(taken); 7260 } else { 7261 branch32(JITCompiler::Equal, left.payloadGPR(), right.payloadGPR(), taken); 7262 jump(notTaken); 7263 } 7264 #endif 7164 7265 } 7165 7266 … … 11433 11534 } 11434 11535 11536 void SpeculativeJIT::speculateNotDouble(Edge edge, JSValueRegs regs, GPRReg tempGPR) 11537 { 11538 if (!needsTypeCheck(edge, ~SpecFullDouble)) 11539 return; 11540 11541 JITCompiler::Jump done; 11542 11543 bool mayBeInt32 = needsTypeCheck(edge, ~SpecInt32Only); 11544 if (mayBeInt32) 11545 done = m_jit.branchIfInt32(regs); 11546 11547 DFG_TYPE_CHECK(regs, edge, ~SpecFullDouble, m_jit.branchIfNumber(regs, tempGPR)); 11548 11549 if (mayBeInt32) 11550 done.link(&m_jit); 11551 } 11552 11435 11553 void SpeculativeJIT::speculateNotDouble(Edge edge) 11436 11554 { … … 11443 11561 GPRReg tempGPR = temp.gpr(); 11444 11562 11445 JITCompiler::Jump done = m_jit.branchIfInt32(regs); 11563 speculateNotDouble(edge, regs, tempGPR); 11564 } 11565 11566 void SpeculativeJIT::speculateNeitherDoubleNorHeapBigIntNorString(Edge edge, JSValueRegs regs, GPRReg tempGPR) 11567 { 11568 if (!needsTypeCheck(edge, ~(SpecFullDouble | SpecString))) 11569 return; 11570 11571 MacroAssembler::JumpList done; 11572 11573 bool mayBeInt32 = needsTypeCheck(edge, ~SpecInt32Only); 11574 if (mayBeInt32) 11575 done.append(m_jit.branchIfInt32(regs)); 11576 11446 11577 DFG_TYPE_CHECK(regs, edge, ~SpecFullDouble, m_jit.branchIfNumber(regs, tempGPR)); 11447 done.link(&m_jit); 11578 11579 bool mayNotBeCell = needsTypeCheck(edge, SpecCell); 11580 if (mayNotBeCell) 11581 done.append(m_jit.branchIfNotCell(regs)); 11582 11583 DFG_TYPE_CHECK(regs, edge, ~SpecString, m_jit.branchIfString(regs.payloadGPR())); 11584 DFG_TYPE_CHECK(regs, edge, ~SpecHeapBigInt, m_jit.branchIfHeapBigInt(regs.payloadGPR())); 11585 11586 if (mayBeInt32 || mayNotBeCell) 11587 done.link(&m_jit); 11588 } 11589 11590 void SpeculativeJIT::speculateNeitherDoubleNorHeapBigIntNorString(Edge edge) 11591 { 11592 if (!needsTypeCheck(edge, ~(SpecFullDouble | SpecString))) 11593 return; 11594 11595 JSValueOperand operand(this, edge, ManualOperandSpeculation); 11596 GPRTemporary temp(this); 11597 JSValueRegs regs = operand.jsValueRegs(); 11598 GPRReg tempGPR = temp.gpr(); 11599 11600 speculateNeitherDoubleNorHeapBigIntNorString(edge, regs, tempGPR); 11448 11601 } 11449 11602 … … 11632 11785 case NotDoubleUse: 11633 11786 speculateNotDouble(edge); 11787 break; 11788 case NeitherDoubleNorHeapBigIntNorStringUse: 11789 speculateNeitherDoubleNorHeapBigIntNorString(edge); 11634 11790 break; 11635 11791 case OtherUse: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r278465 r278568 1190 1190 void compileHeapBigIntEquality(Node*); 1191 1191 void compilePeepHoleSymbolEquality(Node*, Node* branchNode); 1192 void compileNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality(Node*, Edge notDoubleEdge, Edge neitherDoubleNorHeapBigIntNorStringEdge); 1193 void compilePeepHoleNotDoubleNeitherDoubleNorHeapBigIntNorStringStrictEquality(Node*, Node* branchNode, Edge notDoubleEdge, Edge neitherDoubleNorHeapBigIntNorStringEdge); 1192 1194 void compileSymbolUntypedEquality(Node*, Edge symbolEdge, Edge untypedEdge); 1193 1195 … … 1672 1674 void speculateNotCell(Edge); 1673 1675 void speculateNotCellNorBigInt(Edge); 1676 void speculateNotDouble(Edge, JSValueRegs, GPRReg temp); 1674 1677 void speculateNotDouble(Edge); 1678 void speculateNeitherDoubleNorHeapBigIntNorString(Edge, JSValueRegs, GPRReg temp); 1679 void speculateNeitherDoubleNorHeapBigIntNorString(Edge); 1675 1680 void speculateOther(Edge, JSValueRegs, GPRReg temp); 1676 1681 void speculateOther(Edge, JSValueRegs); -
trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp
r278465 r278568 174 174 out.print("NotDouble"); 175 175 return; 176 case NeitherDoubleNorHeapBigIntNorStringUse: 177 out.print("NeitherDoubleNorHeapBigIntNorString"); 178 return; 176 179 case KnownOtherUse: 177 180 out.print("KnownOther"); -
trunk/Source/JavaScriptCore/dfg/DFGUseKind.h
r278465 r278568 83 83 NotCellNorBigIntUse, 84 84 NotDoubleUse, 85 NeitherDoubleNorHeapBigIntNorStringUse, 85 86 KnownOtherUse, 86 87 OtherUse, … … 191 192 case NotDoubleUse: 192 193 return ~SpecFullDouble; 194 case NeitherDoubleNorHeapBigIntNorStringUse: 195 return ~SpecFullDouble & ~SpecHeapBigInt & ~SpecString; 193 196 case KnownOtherUse: 194 197 case OtherUse: … … 310 313 case NotCellNorBigIntUse: 311 314 case NotDoubleUse: 315 case NeitherDoubleNorHeapBigIntNorStringUse: 312 316 return false; 313 317 default: -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r278465 r278568 530 530 case DoubleRepAnyIntUse: 531 531 case NotDoubleUse: 532 case NeitherDoubleNorHeapBigIntNorStringUse: 532 533 // These are OK. 533 534 break; -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r278476 r278568 9503 9503 9504 9504 if (m_node->isBinaryUseKind(MiscUse, UntypedUse) 9505 || m_node->isBinaryUseKind(UntypedUse, MiscUse)) { 9505 || m_node->isBinaryUseKind(UntypedUse, MiscUse) 9506 #if !USE(BIGINT32) 9507 || m_node->isBinaryUseKind(NotDoubleUse, NeitherDoubleNorHeapBigIntNorStringUse) 9508 || m_node->isBinaryUseKind(NeitherDoubleNorHeapBigIntNorStringUse, NotDoubleUse)) { 9509 #else 9510 ) { 9511 #endif 9506 9512 speculate(m_node->child1()); 9507 9513 speculate(m_node->child2()); … … 18407 18413 speculateNotDouble(edge); 18408 18414 break; 18415 case NeitherDoubleNorHeapBigIntNorStringUse: 18416 speculateNeitherDoubleNorHeapBigIntNorString(edge); 18417 break; 18409 18418 case OtherUse: 18410 18419 speculateOther(edge); … … 18466 18475 LBasicBlock lastNext = m_out.appendTo(isNotInt32, continuation); 18467 18476 FTL_TYPE_CHECK(jsValueValue(value), edge, ~SpecFullDouble, isNumber(value)); 18477 m_out.jump(continuation); 18478 18479 m_out.appendTo(continuation, lastNext); 18480 } 18481 18482 void speculateNeitherDoubleNorHeapBigIntNorString(Edge edge) 18483 { 18484 if (!m_interpreter.needsTypeCheck(edge)) 18485 return; 18486 18487 LValue value = lowJSValue(edge, ManualOperandSpeculation); 18488 18489 LBasicBlock isNotInt32 = m_out.newBlock(); 18490 LBasicBlock isCellBlock = m_out.newBlock(); 18491 LBasicBlock continuation = m_out.newBlock(); 18492 18493 m_out.branch(isInt32(value, provenType(edge)), unsure(continuation), unsure(isNotInt32)); 18494 18495 LBasicBlock lastNext = m_out.appendTo(isNotInt32, isCellBlock); 18496 FTL_TYPE_CHECK(jsValueValue(value), edge, ~SpecFullDouble, isNumber(value)); 18497 m_out.branch(isCell(value, provenType(edge)), unsure(isCellBlock), unsure(continuation)); 18498 18499 m_out.appendTo(isCellBlock, continuation); 18500 FTL_TYPE_CHECK(jsValueValue(value), edge, ~SpecString, isString(value)); 18501 FTL_TYPE_CHECK(jsValueValue(value), edge, ~SpecHeapBigInt, isHeapBigInt(value)); 18468 18502 m_out.jump(continuation); 18469 18503
Note:
See TracChangeset
for help on using the changeset viewer.