Changeset 156019 in webkit for trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
- Timestamp:
- Sep 17, 2013, 6:31:04 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r156016 r156019 152 152 type = m_out.int32; 153 153 break; 154 case NodeResultInt52: 155 type = m_out.int64; 156 break; 154 157 case NodeResultBoolean: 155 158 type = m_out.boolean; … … 240 243 break; 241 244 case JSConstant: 242 compileJSConstant();243 245 break; 244 246 case WeakJSConstant: … … 462 464 m_out.set(lowInt32(m_node->child1()), destination); 463 465 break; 466 case MachineIntUse: 467 m_out.set(lowInt52(m_node->child1()), destination); 468 break; 464 469 case BooleanUse: 465 470 m_out.set(lowBoolean(m_node->child1()), destination); … … 487 492 case NodeResultInt32: 488 493 setInt32(m_out.get(source)); 494 break; 495 case NodeResultInt52: 496 setInt52(m_out.get(source)); 489 497 break; 490 498 case NodeResultBoolean: … … 592 600 } 593 601 602 case FlushedInt52: { 603 LValue value = lowInt52(m_node->child1()); 604 m_out.store64(value, addressFor(variable->local())); 605 m_valueSources.operand(variable->local()) = ValueSource(Int52InJSStack); 606 return; 607 } 608 594 609 case FlushedCell: { 595 610 LValue value = lowCell(m_node->child1()); … … 656 671 } 657 672 673 case MachineIntUse: { 674 if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52) 675 && !m_state.forNode(m_node->child2()).couldBeType(SpecInt52)) { 676 Int52Kind kind; 677 LValue left = lowWhicheverInt52(m_node->child1(), kind); 678 LValue right = lowInt52(m_node->child2(), kind); 679 setInt52(m_out.add(left, right), kind); 680 break; 681 } 682 683 LValue left = lowInt52(m_node->child1()); 684 LValue right = lowInt52(m_node->child2()); 685 LValue result = m_out.addWithOverflow64(left, right); 686 speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1)); 687 setInt52(m_out.extractValue(result, 0)); 688 break; 689 } 690 658 691 case NumberUse: { 659 692 setDouble( … … 683 716 speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1)); 684 717 setInt32(m_out.extractValue(result, 0)); 718 break; 719 } 720 721 case MachineIntUse: { 722 if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52) 723 && !m_state.forNode(m_node->child2()).couldBeType(SpecInt52)) { 724 Int52Kind kind; 725 LValue left = lowWhicheverInt52(m_node->child1(), kind); 726 LValue right = lowInt52(m_node->child2(), kind); 727 setInt52(m_out.sub(left, right), kind); 728 break; 729 } 730 731 LValue left = lowInt52(m_node->child1()); 732 LValue right = lowInt52(m_node->child2()); 733 LValue result = m_out.subWithOverflow64(left, right); 734 speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1)); 735 setInt52(m_out.extractValue(result, 0)); 685 736 break; 686 737 } … … 728 779 729 780 setInt32(result); 781 break; 782 } 783 784 case MachineIntUse: { 785 Int52Kind kind; 786 LValue left = lowWhicheverInt52(m_node->child1(), kind); 787 LValue right = lowInt52(m_node->child2(), opposite(kind)); 788 789 LValue overflowResult = m_out.mulWithOverflow64(left, right); 790 speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1)); 791 LValue result = m_out.extractValue(overflowResult, 0); 792 793 if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) { 794 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case")); 795 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation")); 796 797 m_out.branch(m_out.notZero64(result), continuation, slowCase); 798 799 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation); 800 speculate(NegativeZero, noValue(), 0, m_out.lessThan(left, m_out.int64Zero)); 801 speculate(NegativeZero, noValue(), 0, m_out.lessThan(right, m_out.int64Zero)); 802 m_out.jump(continuation); 803 m_out.appendTo(continuation, lastNext); 804 } 805 806 setInt52(result); 730 807 break; 731 808 } … … 1030 1107 1031 1108 setInt32(result); 1109 break; 1110 } 1111 1112 case MachineIntUse: { 1113 if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)) { 1114 Int52Kind kind; 1115 LValue value = lowWhicheverInt52(m_node->child1(), kind); 1116 LValue result = m_out.neg(value); 1117 if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) 1118 speculate(NegativeZero, noValue(), 0, m_out.isZero64(result)); 1119 setInt52(result, kind); 1120 break; 1121 } 1122 1123 LValue value = lowInt52(m_node->child1()); 1124 LValue overflowResult = m_out.subWithOverflow64(m_out.int64Zero, value); 1125 speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1)); 1126 LValue result = m_out.extractValue(overflowResult, 0); 1127 speculate(NegativeZero, noValue(), 0, m_out.isZero64(result)); 1128 setInt52(result); 1032 1129 break; 1033 1130 } … … 1474 1571 1475 1572 FTL_TYPE_CHECK( 1476 doubleValue(value), child3, Spec RealNumber,1573 doubleValue(value), child3, SpecFullRealNumber, 1477 1574 m_out.doubleNotEqualOrUnordered(value, value)); 1478 1575 … … 1709 1806 { 1710 1807 if (m_node->isBinaryUseKind(Int32Use) 1808 || m_node->isBinaryUseKind(MachineIntUse) 1711 1809 || m_node->isBinaryUseKind(NumberUse) 1712 1810 || m_node->isBinaryUseKind(ObjectUse)) { … … 1732 1830 setBoolean( 1733 1831 m_out.equal(lowInt32(m_node->child1()), lowInt32(m_node->child2()))); 1832 return; 1833 } 1834 1835 if (m_node->isBinaryUseKind(MachineIntUse)) { 1836 Int52Kind kind; 1837 LValue left = lowWhicheverInt52(m_node->child1(), kind); 1838 LValue right = lowInt52(m_node->child2(), kind); 1839 setBoolean(m_out.equal(left, right)); 1734 1840 return; 1735 1841 } … … 1783 1889 } 1784 1890 1891 if (m_node->isBinaryUseKind(MachineIntUse)) { 1892 Int52Kind kind; 1893 LValue left = lowWhicheverInt52(m_node->child1(), kind); 1894 LValue right = lowInt52(m_node->child2(), kind); 1895 setBoolean(m_out.lessThan(left, right)); 1896 return; 1897 } 1898 1785 1899 if (m_node->isBinaryUseKind(NumberUse)) { 1786 1900 setBoolean( … … 1797 1911 setBoolean( 1798 1912 m_out.lessThanOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2()))); 1913 return; 1914 } 1915 1916 if (m_node->isBinaryUseKind(MachineIntUse)) { 1917 Int52Kind kind; 1918 LValue left = lowWhicheverInt52(m_node->child1(), kind); 1919 LValue right = lowInt52(m_node->child2(), kind); 1920 setBoolean(m_out.lessThanOrEqual(left, right)); 1799 1921 return; 1800 1922 } … … 1818 1940 } 1819 1941 1942 if (m_node->isBinaryUseKind(MachineIntUse)) { 1943 Int52Kind kind; 1944 LValue left = lowWhicheverInt52(m_node->child1(), kind); 1945 LValue right = lowInt52(m_node->child2(), kind); 1946 setBoolean(m_out.greaterThan(left, right)); 1947 return; 1948 } 1949 1820 1950 if (m_node->isBinaryUseKind(NumberUse)) { 1821 1951 setBoolean( … … 1834 1964 m_out.greaterThanOrEqual( 1835 1965 lowInt32(m_node->child1()), lowInt32(m_node->child2()))); 1966 return; 1967 } 1968 1969 if (m_node->isBinaryUseKind(MachineIntUse)) { 1970 Int52Kind kind; 1971 LValue left = lowWhicheverInt52(m_node->child1(), kind); 1972 LValue right = lowInt52(m_node->child2(), kind); 1973 setBoolean(m_out.greaterThanOrEqual(left, right)); 1836 1974 return; 1837 1975 } … … 2353 2491 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use)); 2354 2492 2493 if (edge->hasConstant()) { 2494 JSValue value = m_graph.valueOfJSConstant(edge.node()); 2495 if (!value.isInt32()) { 2496 terminate(Uncountable); 2497 return m_out.int32Zero; 2498 } 2499 return m_out.constInt32(value.asInt32()); 2500 } 2501 2355 2502 LoweredNodeValue value = m_int32Values.get(edge.node()); 2356 2503 if (isValid(value)) 2357 2504 return value.value(); 2505 2506 value = m_strictInt52Values.get(edge.node()); 2507 if (isValid(value)) 2508 return strictInt52ToInt32(edge, value.value()); 2509 2510 value = m_int52Values.get(edge.node()); 2511 if (isValid(value)) 2512 return strictInt52ToInt32(edge, int52ToStrictInt52(value.value())); 2358 2513 2359 2514 value = m_jsValueValues.get(edge.node()); … … 2372 2527 } 2373 2528 2529 enum Int52Kind { StrictInt52, Int52 }; 2530 LValue lowInt52(Edge edge, Int52Kind kind, OperandSpeculationMode mode = AutomaticOperandSpeculation) 2531 { 2532 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse); 2533 2534 if (edge->hasConstant()) { 2535 JSValue value = m_graph.valueOfJSConstant(edge.node()); 2536 if (!value.isMachineInt()) { 2537 terminate(Uncountable); 2538 return m_out.int64Zero; 2539 } 2540 int64_t result = value.asMachineInt(); 2541 if (kind == Int52) 2542 result <<= JSValue::int52ShiftAmount; 2543 return m_out.constInt64(result); 2544 } 2545 2546 LoweredNodeValue value; 2547 2548 switch (kind) { 2549 case Int52: 2550 value = m_int52Values.get(edge.node()); 2551 if (isValid(value)) 2552 return value.value(); 2553 2554 value = m_strictInt52Values.get(edge.node()); 2555 if (isValid(value)) 2556 return strictInt52ToInt52(value.value()); 2557 break; 2558 2559 case StrictInt52: 2560 value = m_strictInt52Values.get(edge.node()); 2561 if (isValid(value)) 2562 return value.value(); 2563 2564 value = m_int52Values.get(edge.node()); 2565 if (isValid(value)) 2566 return int52ToStrictInt52(value.value()); 2567 break; 2568 } 2569 2570 value = m_int32Values.get(edge.node()); 2571 if (isValid(value)) { 2572 return setInt52WithStrictValue( 2573 edge.node(), m_out.signExt(value.value(), m_out.int64), kind); 2574 } 2575 2576 RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecInt52)); 2577 2578 value = m_jsValueValues.get(edge.node()); 2579 if (isValid(value)) { 2580 LValue boxedResult = value.value(); 2581 FTL_TYPE_CHECK( 2582 jsValueValue(boxedResult), edge, SpecMachineInt, isNotInt32(boxedResult)); 2583 return setInt52WithStrictValue( 2584 edge.node(), m_out.signExt(unboxInt32(boxedResult), m_out.int64), kind); 2585 } 2586 2587 RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecMachineInt)); 2588 terminate(Uncountable); 2589 return m_out.int64Zero; 2590 } 2591 2592 LValue lowInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) 2593 { 2594 return lowInt52(edge, Int52, mode); 2595 } 2596 2597 LValue lowStrictInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) 2598 { 2599 return lowInt52(edge, StrictInt52, mode); 2600 } 2601 2602 bool betterUseStrictInt52(Node* node) 2603 { 2604 return !isValid(m_int52Values.get(node)); 2605 } 2606 bool betterUseStrictInt52(Edge edge) 2607 { 2608 return betterUseStrictInt52(edge.node()); 2609 } 2610 template<typename T> 2611 Int52Kind bestInt52Kind(T node) 2612 { 2613 return betterUseStrictInt52(node) ? StrictInt52 : Int52; 2614 } 2615 Int52Kind opposite(Int52Kind kind) 2616 { 2617 switch (kind) { 2618 case Int52: 2619 return StrictInt52; 2620 case StrictInt52: 2621 return Int52; 2622 } 2623 RELEASE_ASSERT_NOT_REACHED(); 2624 } 2625 2626 LValue lowWhicheverInt52(Edge edge, Int52Kind& kind, OperandSpeculationMode mode = AutomaticOperandSpeculation) 2627 { 2628 kind = bestInt52Kind(edge); 2629 return lowInt52(edge, kind, mode); 2630 } 2631 2374 2632 LValue lowCell(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) 2375 2633 { 2376 2634 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind())); 2635 2636 if (edge->op() == JSConstant) { 2637 JSValue value = m_graph.valueOfJSConstant(edge.node()); 2638 if (!value.isCell()) { 2639 terminate(Uncountable); 2640 return m_out.intPtrZero; 2641 } 2642 return m_out.constIntPtr(value.asCell()); 2643 } 2377 2644 2378 2645 LoweredNodeValue value = m_jsValueValues.get(edge.node()); … … 2419 2686 { 2420 2687 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse); 2688 2689 if (edge->hasConstant()) { 2690 JSValue value = m_graph.valueOfJSConstant(edge.node()); 2691 if (!value.isBoolean()) { 2692 terminate(Uncountable); 2693 return m_out.booleanFalse; 2694 } 2695 return m_out.constBool(value.asBoolean()); 2696 } 2421 2697 2422 2698 LoweredNodeValue value = m_booleanValues.get(edge.node()); … … 2443 2719 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind())); 2444 2720 2721 if (edge->hasConstant()) { 2722 JSValue value = m_graph.valueOfJSConstant(edge.node()); 2723 if (!value.isNumber()) { 2724 terminate(Uncountable); 2725 return m_out.doubleZero; 2726 } 2727 return m_out.constDouble(value.asNumber()); 2728 } 2729 2445 2730 LoweredNodeValue value = m_doubleValues.get(edge.node()); 2446 2731 if (isValid(value)) … … 2454 2739 } 2455 2740 2741 value = m_strictInt52Values.get(edge.node()); 2742 if (isValid(value)) 2743 return strictInt52ToDouble(edge, value.value()); 2744 2745 value = m_int52Values.get(edge.node()); 2746 if (isValid(value)) 2747 return strictInt52ToDouble(edge, int52ToStrictInt52(value.value())); 2748 2456 2749 value = m_jsValueValues.get(edge.node()); 2457 2750 if (isValid(value)) { … … 2473 2766 2474 2767 FTL_TYPE_CHECK( 2475 jsValueValue(boxedResult), edge, Spec Number, isCellOrMisc(boxedResult));2768 jsValueValue(boxedResult), edge, SpecFullNumber, isCellOrMisc(boxedResult)); 2476 2769 2477 2770 ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedResult)); … … 2486 2779 } 2487 2780 2488 RELEASE_ASSERT(!(m_state.forNode(edge).m_type & Spec Number));2781 RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecFullNumber)); 2489 2782 terminate(Uncountable); 2490 2783 return m_out.doubleZero; … … 2494 2787 { 2495 2788 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse); 2789 2790 if (edge->hasConstant()) 2791 return m_out.constInt64(JSValue::encode(m_graph.valueOfJSConstant(edge.node()))); 2496 2792 2497 2793 LoweredNodeValue value = m_jsValueValues.get(edge.node()); … … 2506 2802 } 2507 2803 2804 value = m_strictInt52Values.get(edge.node()); 2805 if (isValid(value)) 2806 return strictInt52ToJSValue(value.value()); 2807 2808 value = m_int52Values.get(edge.node()); 2809 if (isValid(value)) 2810 return strictInt52ToJSValue(int52ToStrictInt52(value.value())); 2811 2508 2812 value = m_booleanValues.get(edge.node()); 2509 2813 if (isValid(value)) { … … 2533 2837 setStorage(edge.node(), result); 2534 2838 return result; 2839 } 2840 2841 LValue strictInt52ToInt32(Edge edge, LValue value) 2842 { 2843 LValue result = m_out.castToInt32(value); 2844 FTL_TYPE_CHECK( 2845 noValue(), edge, SpecInt32, 2846 m_out.notEqual(m_out.signExt(result, m_out.int64), value)); 2847 setInt32(edge.node(), result); 2848 return result; 2849 } 2850 2851 LValue strictInt52ToDouble(Edge edge, LValue value) 2852 { 2853 LValue result = m_out.intToDouble(value); 2854 setDouble(edge.node(), result); 2855 return result; 2856 } 2857 2858 LValue strictInt52ToJSValue(LValue value) 2859 { 2860 LBasicBlock isInt32 = FTL_NEW_BLOCK(m_out, ("strictInt52ToJSValue isInt32 case")); 2861 LBasicBlock isDouble = FTL_NEW_BLOCK(m_out, ("strictInt52ToJSValue isDouble case")); 2862 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("strictInt52ToJSValue continuation")); 2863 2864 Vector<ValueFromBlock, 2> results; 2865 2866 LValue int32Value = m_out.castToInt32(value); 2867 m_out.branch( 2868 m_out.equal(m_out.signExt(int32Value, m_out.int64), value), 2869 isInt32, isDouble); 2870 2871 LBasicBlock lastNext = m_out.appendTo(isInt32, isDouble); 2872 2873 results.append(m_out.anchor(boxInt32(int32Value))); 2874 m_out.jump(continuation); 2875 2876 m_out.appendTo(isDouble, continuation); 2877 2878 results.append(m_out.anchor(boxDouble(m_out.intToDouble(value)))); 2879 m_out.jump(continuation); 2880 2881 m_out.appendTo(continuation, lastNext); 2882 return m_out.phi(m_out.int64, results); 2883 } 2884 2885 LValue setInt52WithStrictValue(Node* node, LValue value, Int52Kind kind) 2886 { 2887 switch (kind) { 2888 case StrictInt52: 2889 setStrictInt52(node, value); 2890 return value; 2891 2892 case Int52: 2893 value = strictInt52ToInt52(value); 2894 setInt52(node, value); 2895 return value; 2896 } 2897 2898 RELEASE_ASSERT_NOT_REACHED(); 2899 return 0; 2900 } 2901 2902 LValue strictInt52ToInt52(LValue value) 2903 { 2904 return m_out.shl(value, m_out.constInt64(JSValue::int52ShiftAmount)); 2905 } 2906 2907 LValue int52ToStrictInt52(LValue value) 2908 { 2909 return m_out.aShr(value, m_out.constInt64(JSValue::int52ShiftAmount)); 2535 2910 } 2536 2911 … … 2795 3170 LValue value = lowDouble(edge); 2796 3171 FTL_TYPE_CHECK( 2797 doubleValue(value), edge, Spec RealNumber,3172 doubleValue(value), edge, SpecFullRealNumber, 2798 3173 m_out.doubleNotEqualOrUnordered(value, value)); 2799 3174 } … … 2803 3178 lowBoolean(edge); 2804 3179 } 2805 3180 2806 3181 bool masqueradesAsUndefinedWatchpointIsStillValid() 2807 3182 { … … 2934 3309 break; 2935 3310 3311 case FlushedInt52: 3312 m_valueSources[i] = ValueSource(Int52InJSStack); 3313 break; 3314 2936 3315 case FlushedDouble: 2937 3316 m_valueSources[i] = ValueSource(DoubleInJSStack); … … 3036 3415 case Int32InJSStack: 3037 3416 exit.m_values[i] = ExitValue::inJSStackAsInt32(); 3417 break; 3418 case Int52InJSStack: 3419 exit.m_values[i] = ExitValue::inJSStackAsInt52(); 3038 3420 break; 3039 3421 case DoubleInJSStack: … … 3140 3522 } 3141 3523 3524 value = m_int52Values.get(node); 3525 if (isValid(value)) { 3526 addExitArgument(exit, arguments, index, ValueFormatInt52, value.value()); 3527 return; 3528 } 3529 3530 value = m_strictInt52Values.get(node); 3531 if (isValid(value)) { 3532 addExitArgument(exit, arguments, index, ValueFormatStrictInt52, value.value()); 3533 return; 3534 } 3535 3142 3536 value = m_booleanValues.get(node); 3143 3537 if (isValid(value)) { … … 3243 3637 m_int32Values.set(node, LoweredNodeValue(value, m_highBlock)); 3244 3638 } 3639 void setInt52(Node* node, LValue value) 3640 { 3641 m_int52Values.set(node, LoweredNodeValue(value, m_highBlock)); 3642 } 3643 void setStrictInt52(Node* node, LValue value) 3644 { 3645 m_strictInt52Values.set(node, LoweredNodeValue(value, m_highBlock)); 3646 } 3647 void setInt52(Node* node, LValue value, Int52Kind kind) 3648 { 3649 switch (kind) { 3650 case Int52: 3651 setInt52(node, value); 3652 return; 3653 3654 case StrictInt52: 3655 setStrictInt52(node, value); 3656 return; 3657 } 3658 3659 RELEASE_ASSERT_NOT_REACHED(); 3660 } 3245 3661 void setJSValue(Node* node, LValue value) 3246 3662 { … … 3263 3679 { 3264 3680 setInt32(m_node, value); 3681 } 3682 void setInt52(LValue value) 3683 { 3684 setInt52(m_node, value); 3685 } 3686 void setStrictInt52(LValue value) 3687 { 3688 setStrictInt52(m_node, value); 3689 } 3690 void setInt52(LValue value, Int52Kind kind) 3691 { 3692 setInt52(m_node, value, kind); 3265 3693 } 3266 3694 void setJSValue(LValue value) … … 3343 3771 3344 3772 HashMap<Node*, LoweredNodeValue> m_int32Values; 3773 HashMap<Node*, LoweredNodeValue> m_strictInt52Values; 3774 HashMap<Node*, LoweredNodeValue> m_int52Values; 3345 3775 HashMap<Node*, LoweredNodeValue> m_jsValueValues; 3346 3776 HashMap<Node*, LoweredNodeValue> m_booleanValues;
Note:
See TracChangeset
for help on using the changeset viewer.