Changeset 260730 in webkit
- Timestamp:
- Apr 26, 2020 2:11:50 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r260720 r260730 1 2020-04-26 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] ValueAdd, VaueSub, ValueMul, Inc, Dec should say SpecBigInt32 prediction based on ArithProfile 4 https://bugs.webkit.org/show_bug.cgi?id=211038 5 6 Reviewed by Filip Pizlo. 7 8 * stress/bigint32-add-overflow.js: Added. 9 (shouldBe): 10 (add): 11 (noInline): 12 * stress/bigint32-dec-overflow.js: Added. 13 (shouldBe): 14 (dec): 15 (noInline): 16 * stress/bigint32-inc-overflow.js: Added. 17 (shouldBe): 18 (inc): 19 (noInline): 20 * stress/bigint32-mul-overflow.js: Added. 21 (shouldBe): 22 (mul): 23 (noInline): 24 * stress/bigint32-sub-overflow.js: Added. 25 (shouldBe): 26 (sub): 27 (noInline): 28 1 29 2020-04-25 Yusuke Suzuki <ysuzuki@apple.com> 2 30 -
trunk/Source/JavaScriptCore/ChangeLog
r260722 r260730 1 2020-04-26 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] ValueAdd, VaueSub, ValueMul, Inc, Dec should say SpecBigInt32 prediction based on ArithProfile 4 https://bugs.webkit.org/show_bug.cgi?id=211038 5 6 Reviewed by Filip Pizlo. 7 8 This patch adds profile feedback to ValueAdd, ValueSub, ValueMul, Inc, Dec to say SpecBigInt32 prediction. 9 10 Our HeapBigInt v.s. BigInt32 strategy is simpler than Double v.s. Int32 strategy: we always 11 prefer BigInt32 over HeapBigInt. This is because HeapBigInt calculation and conversion require 12 much higher cost than BigInt32. This tradeoff is largely different from Double v.s. Int32. 13 So keeping HeapBigInt is simply inefficient when we can use BigInt32. 14 15 This means that ArithProfile's feedback is also very simple. If we see HeapBigInt, this means 16 overflow happens. In DFG, we propagate this information to ValueAdd, ValueSub, and ValueMul nodes 17 and record it in DFGNodeFlags. And based on this information, we change the prediction and 18 speculation in prediction propagation and fixup phase. 19 20 We change exit reason from Overflow to BigInt32Overflow since Overflow is solely used for Int32 case, 21 and we have Int52Overflow for Int52 case. We should have BigInt32Overflow for BigInt32 to precisely 22 record and tell about what happens in DFG as a feedback for the next compilation. 23 24 We add BigInt32 speculation for ValueSub. Previously, we missed that in fixup phase and we always 25 speculate ValueSub with AnyBigIntUse or HeapBigIntUse. Now it can use BigInt32Use. 26 27 We also fix Inc / Dec's fixup phase to use BigInt path. Previously, it was always using UntypedUse since 28 `node->child1()->shouldSpeculateUntypedForArithmetic()` returns true for BigInt. We fix the ordering of 29 speculation attempts as it is done in the other places in fixup phase. 30 31 This patch offers 7.9% performance improvement in sunspider-sha1-big-int. 32 33 ToT Patched 34 35 sunspider-sha1-big-int 134.5668+-2.8695 ^ 124.6743+-0.7541 ^ definitely 1.0793x faster 36 37 * bytecode/ExitKind.cpp: 38 (JSC::exitKindToString): 39 * bytecode/ExitKind.h: 40 * bytecode/SpeculatedType.h: 41 * dfg/DFGAbstractInterpreterInlines.h: 42 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 43 * dfg/DFGByteCodeParser.cpp: 44 (JSC::DFG::ByteCodeParser::makeSafe): 45 (JSC::DFG::ByteCodeParser::makeDivSafe): 46 * dfg/DFGFixupPhase.cpp: 47 (JSC::DFG::FixupPhase::fixupNode): 48 * dfg/DFGGraph.h: 49 (JSC::DFG::Graph::binaryArithShouldSpeculateBigInt32): 50 (JSC::DFG::Graph::unaryArithShouldSpeculateBigInt32): 51 * dfg/DFGNode.h: 52 (JSC::DFG::Node::mayHaveBigInt32Result): 53 (JSC::DFG::Node::mayHaveHeapBigIntResult): 54 (JSC::DFG::Node::mayHaveBigIntResult): 55 (JSC::DFG::Node::canSpeculateBigInt32): 56 (JSC::DFG::Node::canSpeculateInt52): 57 * dfg/DFGNodeFlags.cpp: 58 (JSC::DFG::dumpNodeFlags): 59 * dfg/DFGNodeFlags.h: 60 (JSC::DFG::nodeMayHaveHeapBigInt): 61 (JSC::DFG::nodeCanSpeculateBigInt32): 62 * dfg/DFGPredictionPropagationPhase.cpp: 63 * dfg/DFGSpeculativeJIT.cpp: 64 (JSC::DFG::SpeculativeJIT::compileValueAdd): 65 (JSC::DFG::SpeculativeJIT::compileValueSub): 66 (JSC::DFG::SpeculativeJIT::compileValueMul): 67 (JSC::DFG::SpeculativeJIT::compileValueDiv): 68 (JSC::DFG::SpeculativeJIT::speculateHeapBigInt): 69 * ftl/FTLLowerDFGToB3.cpp: 70 (JSC::FTL::DFG::LowerDFGToB3::compileValueAdd): 71 (JSC::FTL::DFG::LowerDFGToB3::compileValueSub): 72 (JSC::FTL::DFG::LowerDFGToB3::compileValueMul): 73 (JSC::FTL::DFG::LowerDFGToB3::compileValueDiv): 74 1 75 2020-04-25 Ross Kirsling <ross.kirsling@sony.com> 2 76 -
trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp
r240114 r260730 89 89 case GenericUnwind: 90 90 return "GenericUnwind"; 91 case BigInt32Overflow: 92 return "BigInt32Overflow"; 91 93 } 92 94 RELEASE_ASSERT_NOT_REACHED(); -
trunk/Source/JavaScriptCore/bytecode/ExitKind.h
r252680 r260730 56 56 ExceptionCheck, // We exited because a direct exception check showed that we threw an exception from a C call. 57 57 GenericUnwind, // We exited because we arrived at this OSR exit from genericUnwind. 58 BigInt32Overflow, // We exited because of an BigInt32 overflow. 58 59 }; 59 60 -
trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h
r260331 r260730 101 101 static constexpr SpeculatedType SpecHeapBigInt = 1ull << 41; // It's definitely a BigInt that is allocated on the heap 102 102 static constexpr SpeculatedType SpecBigInt32 = 1ull << 42; // It's definitely a small BigInt that is inline the JSValue 103 #if USE(BIGINT32) 103 104 static constexpr SpeculatedType SpecBigInt = SpecBigInt32 | SpecHeapBigInt; 105 #else 106 // We should not include SpecBigInt32. We are using SpecBigInt in various places like prediction. If this includes SpecBigInt32, fixup phase is confused if !USE(BIGINT32) since it is not using AnyBigIntUse. 107 static constexpr SpeculatedType SpecBigInt = SpecHeapBigInt; 108 #endif 104 109 static constexpr SpeculatedType SpecDataViewObject = 1ull << 43; // It's definitely a JSDataView. 105 110 static constexpr SpeculatedType SpecPrimitive = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc | SpecBigInt; // It's any non-Object JSValue. -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r260683 r260730 767 767 // https://bugs.webkit.org/show_bug.cgi?id=210982 768 768 setTypeForNode(node, SpecBigInt); 769 } else if (node-> binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)769 } else if (node->isBinaryUseKind(AnyBigIntUse)) 770 770 setTypeForNode(node, SpecBigInt); 771 else if (node->isBinaryUseKind(BigInt32Use)) 772 setTypeForNode(node, SpecBigInt32); 771 773 else { 772 774 DFG_ASSERT(m_graph, node, node->binaryUseKind() == UntypedUse); … … 1057 1059 // https://bugs.webkit.org/show_bug.cgi?id=210982 1058 1060 setTypeForNode(node, SpecBigInt); 1059 } else if (node-> binaryUseKind() == AnyBigIntUse || node->binaryUseKind() == BigInt32Use)1061 } else if (node->isBinaryUseKind(AnyBigIntUse)) 1060 1062 setTypeForNode(node, SpecBigInt); 1063 else if (node->isBinaryUseKind(BigInt32Use)) 1064 setTypeForNode(node, SpecBigInt32); 1061 1065 else { 1062 1066 clobberWorld(); -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r260585 r260730 1012 1012 if (observed.didObserveNonNumeric()) 1013 1013 node->mergeFlags(NodeMayHaveNonNumericResult); 1014 if (observed.didObserveBigInt()) 1015 node->mergeFlags(NodeMayHaveBigIntResult); 1014 if (observed.didObserveBigInt32()) 1015 node->mergeFlags(NodeMayHaveBigInt32Result); 1016 if (observed.didObserveHeapBigInt() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BigInt32Overflow)) 1017 node->mergeFlags(NodeMayHaveHeapBigIntResult); 1016 1018 break; 1017 1019 } … … 1031 1033 if (arithProfile->didObserveNonNumeric()) 1032 1034 node->mergeFlags(NodeMayHaveNonNumericResult); 1033 if (arithProfile->didObserveBigInt()) 1034 node->mergeFlags(NodeMayHaveBigIntResult); 1035 if (arithProfile->didObserveBigInt32()) 1036 node->mergeFlags(NodeMayHaveBigInt32Result); 1037 if (arithProfile->didObserveHeapBigInt() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BigInt32Overflow)) 1038 node->mergeFlags(NodeMayHaveHeapBigIntResult); 1035 1039 break; 1036 1040 } … … 1050 1054 if (arithProfile->didObserveNonNumeric()) 1051 1055 node->mergeFlags(NodeMayHaveNonNumericResult); 1052 if (arithProfile->didObserveBigInt()) 1053 node->mergeFlags(NodeMayHaveBigIntResult); 1056 if (arithProfile->didObserveBigInt32()) 1057 node->mergeFlags(NodeMayHaveBigInt32Result); 1058 if (arithProfile->didObserveHeapBigInt() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BigInt32Overflow)) 1059 node->mergeFlags(NodeMayHaveHeapBigIntResult); 1054 1060 break; 1055 1061 } … … 1100 1106 1101 1107 BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeIndex(m_currentIndex); 1102 if (arithProfile->didObserveBigInt()) 1103 node->mergeFlags(NodeMayHaveBigIntResult); 1108 1109 if (arithProfile->didObserveBigInt32()) 1110 node->mergeFlags(NodeMayHaveBigInt32Result); 1111 if (arithProfile->didObserveHeapBigInt() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BigInt32Overflow)) 1112 node->mergeFlags(NodeMayHaveHeapBigIntResult); 1104 1113 1105 1114 return node; -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r260683 r260730 189 189 case Inc: 190 190 case Dec: { 191 if (node->child1()->shouldSpeculateBigInt()) { 192 if (node->child1()->shouldSpeculateHeapBigInt()) { 193 // FIXME: the freezing does not appear useful (since the JSCell is kept alive by vm), but it refuses to compile otherwise. 194 // FIXME: we might optimize inc/dec to a specialized function call instead in that case. 195 node->setOp(op == Inc ? ValueAdd : ValueSub); 196 Node* nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecHeapBigInt, JSConstant, node->origin, OpInfo(m_graph.freeze(vm().heapBigIntConstantOne.get()))); 197 node->children.setChild2(Edge(nodeConstantOne)); 198 fixEdge<HeapBigIntUse>(node->child1()); 199 fixEdge<HeapBigIntUse>(node->child2()); 200 // HeapBigInts are cells, so the default of NodeResultJS is good here 201 break; 202 } 203 #if USE(BIGINT32) 204 if (m_graph.unaryArithShouldSpeculateBigInt32(node, FixupPass)) { 205 node->setOp(op == Inc ? ValueAdd : ValueSub); 206 Node* nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBigInt32, JSConstant, node->origin, OpInfo(m_graph.freeze(jsBigInt32(1)))); 207 node->children.setChild2(Edge(nodeConstantOne)); 208 fixEdge<BigInt32Use>(node->child1()); 209 fixEdge<BigInt32Use>(node->child2()); 210 // The default of NodeResultJS is good enough for now. 211 // FIXME: consider having a special representation for small BigInts instead. 212 break; 213 } 214 215 // FIXME: the freezing does not appear useful (since the JSCell is kept alive by vm), but it refuses to compile otherwise. 216 // FIXME: we might optimize inc/dec to a specialized function call instead in that case. 217 node->setOp(op == Inc ? ValueAdd : ValueSub); 218 Node* nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBigInt32, JSConstant, node->origin, OpInfo(m_graph.freeze(jsBigInt32(1)))); 219 node->children.setChild2(Edge(nodeConstantOne)); 220 fixEdge<AnyBigIntUse>(node->child1()); 221 fixEdge<AnyBigIntUse>(node->child2()); 222 // The default of NodeResultJS is good here 223 #endif // USE(BIGINT32) 224 break; 225 } 226 191 227 if (node->child1()->shouldSpeculateUntypedForArithmetic()) { 192 228 fixEdge<UntypedUse>(node->child1()); … … 203 239 fixEdge<Int32Use>(node->child2()); 204 240 node->setResult(NodeResultInt32); 205 } else if (node->child1()->shouldSpeculateHeapBigInt()) {206 // FIXME: the freezing does not appear useful (since the JSCell is kept alive by vm), but it refuses to compile otherwise.207 // FIXME: we might optimize inc/dec to a specialized function call instead in that case.208 node->setOp(op == Inc ? ValueAdd : ValueSub);209 nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecHeapBigInt, JSConstant, node->origin, OpInfo(m_graph.freeze(vm().heapBigIntConstantOne.get())));210 node->children.setChild2(Edge(nodeConstantOne));211 fixEdge<HeapBigIntUse>(node->child1());212 fixEdge<HeapBigIntUse>(node->child2());213 // HeapBigInts are cells, so the default of NodeResultJS is good here214 #if USE(BIGINT32)215 } else if (node->child1()->shouldSpeculateBigInt32()) {216 node->setOp(op == Inc ? ValueAdd : ValueSub);217 nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBigInt32, JSConstant, node->origin, OpInfo(m_graph.freeze(jsBigInt32(1))));218 node->children.setChild2(Edge(nodeConstantOne));219 fixEdge<BigInt32Use>(node->child1());220 fixEdge<BigInt32Use>(node->child2());221 // The default of NodeResultJS is good enough for now.222 // FIXME: consider having a special representation for small BigInts instead.223 } else if (node->child1()->shouldSpeculateBigInt()) {224 // FIXME: the freezing does not appear useful (since the JSCell is kept alive by vm), but it refuses to compile otherwise.225 // FIXME: we might optimize inc/dec to a specialized function call instead in that case.226 node->setOp(op == Inc ? ValueAdd : ValueSub);227 nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBigInt32, JSConstant, node->origin, OpInfo(m_graph.freeze(jsBigInt32(1))));228 node->children.setChild2(Edge(nodeConstantOne));229 fixEdge<AnyBigIntUse>(node->child1());230 fixEdge<AnyBigIntUse>(node->child2());231 // The default of NodeResultJS is good here232 #endif // USE(BIGINT32)233 241 } else if (node->child1()->shouldSpeculateInt52()) { 234 242 node->setOp(op == Inc ? ArithAdd : ArithSub); … … 263 271 264 272 #if USE(BIGINT32) 273 if (m_graph.binaryArithShouldSpeculateBigInt32(node, FixupPass)) { 274 fixEdge<BigInt32Use>(child1); 275 fixEdge<BigInt32Use>(child2); 276 break; 277 } 278 265 279 if (Node::shouldSpeculateBigInt(child1.node(), child2.node())) { 266 280 fixEdge<AnyBigIntUse>(child1); 267 281 fixEdge<AnyBigIntUse>(child2); 268 break; 282 break; 269 283 } 270 284 #endif … … 312 326 fixEdge<HeapBigIntUse>(node->child2()); 313 327 #endif 314 node->clearFlags(NodeMustGenerate); 328 // Shift can throw RangeError. 329 switch (node->op()) { 330 case ValueBitXor: 331 case ValueBitOr: 332 case ValueBitAnd: 333 node->clearFlags(NodeMustGenerate); 334 break; 335 default: 336 break; 337 } 315 338 break; 316 339 } … … 514 537 fixEdge<HeapBigIntUse>(child2); 515 538 #if USE(BIGINT32) 516 } else if ( Node::shouldSpeculateBigInt32(child1.node(), child2.node())) {539 } else if (m_graph.binaryArithShouldSpeculateBigInt32(node, FixupPass)) { 517 540 fixEdge<BigInt32Use>(child1); 518 541 fixEdge<BigInt32Use>(child2); … … 607 630 if (Node::shouldSpeculateBigInt(leftChild.node(), rightChild.node())) { 608 631 #if USE(BIGINT32) 609 if ( Node::shouldSpeculateBigInt32(leftChild.node(), rightChild.node())) {632 if (m_graph.binaryArithShouldSpeculateBigInt32(node, FixupPass)) { 610 633 fixEdge<BigInt32Use>(node->child1()); 611 634 fixEdge<BigInt32Use>(node->child2()); … … 738 761 739 762 case ValuePow: { 740 if (Node::shouldSpeculateHeapBigInt(node->child1().node(), node->child 1().node())) {763 if (Node::shouldSpeculateHeapBigInt(node->child1().node(), node->child2().node())) { 741 764 fixEdge<HeapBigIntUse>(node->child1()); 742 765 fixEdge<HeapBigIntUse>(node->child2()); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r260323 r260730 410 410 && !hasExitSite(node, Int52Overflow); 411 411 } 412 413 #if USE(BIGINT32) 414 bool binaryArithShouldSpeculateBigInt32(Node* node, PredictionPass pass) 415 { 416 if (!node->canSpeculateBigInt32(pass)) 417 return false; 418 if (hasExitSite(node, BigInt32Overflow)) 419 return false; 420 return Node::shouldSpeculateBigInt32(node->child1().node(), node->child2().node()); 421 } 422 423 bool unaryArithShouldSpeculateBigInt32(Node* node, PredictionPass pass) 424 { 425 if (!node->canSpeculateBigInt32(pass)) 426 return false; 427 if (hasExitSite(node, BigInt32Overflow)) 428 return false; 429 return node->child1()->shouldSpeculateBigInt32(); 430 } 431 #endif 412 432 413 433 bool canOptimizeStringObjectAccess(const CodeOrigin&); -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r260331 r260730 1203 1203 } 1204 1204 1205 bool mayHaveBigInt32Result() 1206 { 1207 return m_flags & NodeMayHaveBigInt32Result; 1208 } 1209 1210 bool mayHaveHeapBigIntResult() 1211 { 1212 return m_flags & NodeMayHaveHeapBigIntResult; 1213 } 1214 1205 1215 bool mayHaveBigIntResult() 1206 1216 { 1207 return m _flags & NodeMayHaveBigIntResult;1217 return mayHaveBigInt32Result() || mayHaveHeapBigIntResult(); 1208 1218 } 1209 1219 … … 2867 2877 return nodeCanSpeculateInt52(arithNodeFlags(), source); 2868 2878 } 2879 2880 bool canSpeculateBigInt32(RareCaseProfilingSource source) 2881 { 2882 return nodeCanSpeculateBigInt32(arithNodeFlags(), source); 2883 } 2869 2884 2870 2885 RareCaseProfilingSource sourceFor(PredictionPass pass) … … 2883 2898 { 2884 2899 return canSpeculateInt52(sourceFor(pass)); 2900 } 2901 2902 bool canSpeculateBigInt32(PredictionPass pass) 2903 { 2904 return canSpeculateBigInt32(sourceFor(pass)); 2885 2905 } 2886 2906 -
trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
r237972 r260730 89 89 out.print(comma, "MayHaveDoubleResult"); 90 90 91 if (flags & NodeMayHaveBigIntResult) 92 out.print(comma, "MayHaveBigIntResult"); 91 if (flags & NodeMayHaveBigInt32Result) 92 out.print(comma, "MayHaveBigInt32Result"); 93 94 if (flags & NodeMayHaveHeapBigIntResult) 95 out.print(comma, "MayHaveHeapBigIntResult"); 93 96 94 97 if (flags & NodeMayHaveNonNumericResult) -
trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.h
r260331 r260730 43 43 #define NodeResultBoolean 0x0006 44 44 #define NodeResultStorage 0x0007 45 45 46 46 #define NodeMustGenerate 0x0008 // set on nodes that have side effects, and may not trivially be removed by DCE. 47 47 #define NodeHasVarArgs 0x0010 48 49 #define NodeBehaviorMask 0x007e0 48 50 49 #define NodeMayHaveDoubleResult 0x00020 51 50 #define NodeMayOverflowInt52 0x00040 … … 54 53 #define NodeMayNegZeroInBaseline 0x00200 55 54 #define NodeMayNegZeroInDFG 0x00400 56 #define NodeMayHaveNonNumericResult 0x00800 57 // FIXME: we should have separate flags for HeapBigInt and BigInt32, currently prediction propagation will pessimize things. 58 #define NodeMayHaveBigIntResult 0x01000 59 #define NodeMayHaveNonIntResult (NodeMayHaveDoubleResult | NodeMayHaveNonNumericResult | NodeMayHaveBigIntResult) 60 61 #define NodeBytecodeBackPropMask 0x3e000 62 #define NodeBytecodeUseBottom 0x00000 63 #define NodeBytecodeUsesAsNumber 0x02000 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results. 64 #define NodeBytecodeNeedsNegZero 0x04000 // The result of this computation may be used in a context that observes -0. 65 #define NodeBytecodeUsesAsOther 0x08000 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined). 66 #define NodeBytecodeUsesAsValue (NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther) 67 #define NodeBytecodeUsesAsInt 0x10000 // The result of this computation is known to be used in a context that prefers, but does not require, integer values. 68 #define NodeBytecodeUsesAsArrayIndex 0x20000 // The result of this computation is known to be used in a context that strongly prefers integer values, to the point that we should avoid using doubles if at all possible. 55 #define NodeMayHaveBigInt32Result 0x00800 56 #define NodeMayHaveHeapBigIntResult 0x01000 57 #define NodeMayHaveNonNumericResult 0x02000 58 #define NodeBehaviorMask (NodeMayHaveDoubleResult | NodeMayOverflowInt52 | NodeMayOverflowInt32InBaseline | NodeMayOverflowInt32InDFG | NodeMayNegZeroInBaseline | NodeMayNegZeroInDFG | NodeMayHaveBigInt32Result | NodeMayHaveHeapBigIntResult | NodeMayHaveNonNumericResult) 59 #define NodeMayHaveNonIntResult (NodeMayHaveDoubleResult | NodeMayHaveNonNumericResult | NodeMayHaveBigInt32Result | NodeMayHaveHeapBigIntResult) 60 61 #define NodeBytecodeUseBottom 0x00000 62 #define NodeBytecodeUsesAsNumber 0x04000 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results. 63 #define NodeBytecodeNeedsNegZero 0x08000 // The result of this computation may be used in a context that observes -0. 64 #define NodeBytecodeUsesAsOther 0x10000 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined). 65 #define NodeBytecodeUsesAsInt 0x20000 // The result of this computation is known to be used in a context that prefers, but does not require, integer values. 66 #define NodeBytecodeUsesAsArrayIndex 0x40000 // The result of this computation is known to be used in a context that strongly prefers integer values, to the point that we should avoid using doubles if at all possible. 67 #define NodeBytecodeUsesAsValue (NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther) 68 #define NodeBytecodeBackPropMask (NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex) 69 69 70 70 #define NodeArithFlagsMask (NodeBehaviorMask | NodeBytecodeBackPropMask) 71 71 72 #define NodeIsFlushed 0x40000 // Computed by CPSRethreadingPhase, will tell you which local nodes are backwards-reachable from a Flush.72 #define NodeIsFlushed 0x80000 // Computed by CPSRethreadingPhase, will tell you which local nodes are backwards-reachable from a Flush. 73 73 74 #define NodeMiscFlag1 0x 8000075 #define NodeMiscFlag2 0x 10000074 #define NodeMiscFlag1 0x100000 75 #define NodeMiscFlag2 0x200000 76 76 77 77 typedef uint32_t NodeFlags; … … 159 159 } 160 160 161 static inline bool nodeMayHaveHeapBigInt(NodeFlags flags, RareCaseProfilingSource) 162 { 163 return !!(flags & NodeMayHaveHeapBigIntResult); 164 } 165 166 static inline bool nodeCanSpeculateBigInt32(NodeFlags flags, RareCaseProfilingSource source) 167 { 168 // We always attempt to produce BigInt32 as much as possible. If we see HeapBigInt, we observed overflow. 169 // FIXME: Extend this information by tiered profiling (from Baseline, DFG etc.). 170 // https://bugs.webkit.org/show_bug.cgi?id=211039 171 return !nodeMayHaveHeapBigInt(flags, source); 172 } 173 161 174 // FIXME: Get rid of this. 162 175 // https://bugs.webkit.org/show_bug.cgi?id=131689 -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r260711 r260730 211 211 // left or right is definitely something other than a number. 212 212 changed |= mergePrediction(SpecString); 213 } else if (isBigIntSpeculation(left) && isBigIntSpeculation(right)) 213 } 214 #if USE(BIGINT32) 215 else if (m_graph.binaryArithShouldSpeculateBigInt32(node, m_pass)) 216 changed |= mergePrediction(SpecBigInt32); 217 #endif 218 else if (isBigIntSpeculation(left) && isBigIntSpeculation(right)) 214 219 changed |= mergePrediction(SpecBigInt); 215 220 else { … … 279 284 else 280 285 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); 281 } else if (isBigIntSpeculation(left) && isBigIntSpeculation(right)) 286 } 287 #if USE(BIGINT32) 288 else if (m_graph.binaryArithShouldSpeculateBigInt32(node, m_pass)) 289 changed |= mergePrediction(SpecBigInt32); 290 #endif 291 else if (isBigIntSpeculation(left) && isBigIntSpeculation(right)) 282 292 changed |= mergePrediction(SpecBigInt); 283 293 else { … … 305 315 else 306 316 changed |= mergePrediction(speculatedDoubleTypeForPrediction(prediction)); 307 } else if (isBigIntSpeculation(prediction)) 317 } 318 #if USE(BIGINT32) 319 else if (m_graph.unaryArithShouldSpeculateBigInt32(node, m_pass)) 320 changed |= mergePrediction(SpecBigInt32); 321 #endif 322 else if (isBigIntSpeculation(prediction)) 308 323 changed |= mergePrediction(SpecBigInt); 309 324 else { … … 387 402 else 388 403 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); 389 } else if (op == ValueMul && isBigIntSpeculation(left) && isBigIntSpeculation(right)) 404 } 405 #if USE(BIGINT32) 406 else if (op == ValueMul && m_graph.binaryArithShouldSpeculateBigInt32(node, m_pass)) 407 changed |= mergePrediction(SpecBigInt32); 408 #endif 409 else if (op == ValueMul && isBigIntSpeculation(left) && isBigIntSpeculation(right)) 390 410 changed |= mergePrediction(SpecBigInt); 391 411 else { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r260683 r260730 4027 4027 4028 4028 #if USE(BIGINT32) 4029 // FIXME: Introduce another BigInt32 code generation: binary use kinds are BigIntUse32, but result is SpecAnyInt and accepting overflow. 4030 // Let's distinguish these modes based on result type information by introducing NodeResultBigInt32. 4031 // https://bugs.webkit.org/show_bug.cgi?id=210957 4032 // https://bugs.webkit.org/show_bug.cgi?id=211040 4029 4033 if (node->isBinaryUseKind(BigInt32Use)) { 4030 4034 SpeculateBigInt32Operand left(this, leftChild); … … 4041 4045 m_jit.unboxBigInt32(rightGPR, tempGPR); 4042 4046 4043 // FIXME: add some way to eliminate the overflow check4044 4047 MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, resultGPR, tempGPR, resultGPR); 4045 4048 4046 speculationCheck( Overflow, JSValueRegs(), 0, check);4049 speculationCheck(BigInt32Overflow, JSValueRegs(), 0, check); 4047 4050 4048 4051 m_jit.boxBigInt32(resultGPR); … … 4131 4134 4132 4135 #if USE(BIGINT32) 4136 // FIXME: Introduce another BigInt32 code generation: binary use kinds are BigIntUse32, but result is SpecAnyInt and accepting overflow. 4137 // Let's distinguish these modes based on result type information by introducing NodeResultBigInt32. 4138 // https://bugs.webkit.org/show_bug.cgi?id=210957 4139 // https://bugs.webkit.org/show_bug.cgi?id=211040 4133 4140 if (node->binaryUseKind() == BigInt32Use) { 4134 4141 SpeculateBigInt32Operand left(this, node->child1()); … … 4145 4152 m_jit.unboxBigInt32(rightGPR, tempGPR); 4146 4153 4147 // FIXME: add some way to eliminate the overflow check4148 4154 MacroAssembler::Jump check = m_jit.branchSub32(MacroAssembler::Overflow, resultGPR, tempGPR, resultGPR); 4149 4155 4150 speculationCheck( Overflow, JSValueRegs(), 0, check);4156 speculationCheck(BigInt32Overflow, JSValueRegs(), 0, check); 4151 4157 4152 4158 m_jit.boxBigInt32(resultGPR); … … 4978 4984 4979 4985 #if USE(BIGINT32) 4986 // FIXME: Introduce another BigInt32 code generation: binary use kinds are BigIntUse32, but result is SpecAnyInt and accepting overflow. 4987 // Let's distinguish these modes based on result type information by introducing NodeResultBigInt32. 4988 // https://bugs.webkit.org/show_bug.cgi?id=210957 4989 // https://bugs.webkit.org/show_bug.cgi?id=211040 4980 4990 if (node->binaryUseKind() == BigInt32Use) { 4981 4991 // FIXME: the code between compileValueAdd, compileValueSub and compileValueMul for BigInt32 is nearly identical, so try to get rid of the duplication. … … 4993 5003 m_jit.unboxBigInt32(rightGPR, tempGPR); 4994 5004 4995 // FIXME: add some way to eliminate the overflow check4996 5005 MacroAssembler::Jump check = m_jit.branchMul32(MacroAssembler::Overflow, resultGPR, tempGPR, resultGPR); 4997 5006 4998 speculationCheck( Overflow, JSValueRegs(), 0, check);5007 speculationCheck(BigInt32Overflow, JSValueRegs(), 0, check); 4999 5008 5000 5009 m_jit.boxBigInt32(resultGPR); … … 5210 5219 5211 5220 // FIXME: add a fast path for BigInt32. Currently we go through the slow path, because of how ugly the code for Div gets. 5221 // https://bugs.webkit.org/show_bug.cgi?id=211041 5212 5222 5213 5223 if (node->isBinaryUseKind(HeapBigIntUse)) { … … 10803 10813 void SpeculativeJIT::speculateHeapBigInt(Edge edge) 10804 10814 { 10805 if (!needsTypeCheck(edge, Spec BigInt))10815 if (!needsTypeCheck(edge, SpecHeapBigInt)) 10806 10816 return; 10807 10817 -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r260660 r260730 2144 2144 2145 2145 #if USE(BIGINT32) 2146 // FIXME: Introduce another BigInt32 code generation: binary use kinds are BigIntUse32, but result is SpecAnyInt and accepting overflow. 2147 // Let's distinguish these modes based on result type information by introducing NodeResultBigInt32. 2148 // https://bugs.webkit.org/show_bug.cgi?id=210957 2149 // https://bugs.webkit.org/show_bug.cgi?id=211040 2146 2150 if (m_node->isBinaryUseKind(BigInt32Use)) { 2147 2151 LValue left = lowBigInt32(m_node->child1()); … … 2152 2156 2153 2157 CheckValue* result = m_out.speculateAdd(unboxedLeft, unboxedRight); 2154 blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);2158 blessSpeculation(result, BigInt32Overflow, noValue(), nullptr, m_origin); 2155 2159 2156 2160 LValue boxedResult = boxBigInt32(result); … … 2182 2186 2183 2187 #if USE(BIGINT32) 2188 // FIXME: Introduce another BigInt32 code generation: binary use kinds are BigIntUse32, but result is SpecAnyInt and accepting overflow. 2189 // Let's distinguish these modes based on result type information by introducing NodeResultBigInt32. 2190 // https://bugs.webkit.org/show_bug.cgi?id=210957 2191 // https://bugs.webkit.org/show_bug.cgi?id=211040 2184 2192 if (m_node->isBinaryUseKind(BigInt32Use)) { 2185 2193 LValue left = lowBigInt32(m_node->child1()); … … 2190 2198 2191 2199 CheckValue* result = m_out.speculateSub(unboxedLeft, unboxedRight); 2192 blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);2200 blessSpeculation(result, BigInt32Overflow, noValue(), nullptr, m_origin); 2193 2201 2194 2202 LValue boxedResult = boxBigInt32(result); … … 2220 2228 2221 2229 #if USE(BIGINT32) 2230 // FIXME: Introduce another BigInt32 code generation: binary use kinds are BigIntUse32, but result is SpecAnyInt and accepting overflow. 2231 // Let's distinguish these modes based on result type information by introducing NodeResultBigInt32. 2232 // https://bugs.webkit.org/show_bug.cgi?id=210957 2233 // https://bugs.webkit.org/show_bug.cgi?id=211040 2222 2234 if (m_node->isBinaryUseKind(BigInt32Use)) { 2223 2235 LValue left = lowBigInt32(m_node->child1()); … … 2228 2240 2229 2241 CheckValue* result = m_out.speculateMul(unboxedLeft, unboxedRight); 2230 blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);2242 blessSpeculation(result, BigInt32Overflow, noValue(), nullptr, m_origin); 2231 2243 2232 2244 LValue boxedResult = boxBigInt32(result); … … 2628 2640 JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic); 2629 2641 // FIXME: add a fast path for BigInt32 here 2642 // https://bugs.webkit.org/show_bug.cgi?id=211041 2630 2643 if (m_node->isBinaryUseKind(HeapBigIntUse)) { 2631 2644 LValue left = lowHeapBigInt(m_node->child1());
Note: See TracChangeset
for help on using the changeset viewer.