Changeset 156029 in webkit for trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
- Timestamp:
- Sep 18, 2013, 12:25:52 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r156019 r156029 152 152 type = m_out.int32; 153 153 break; 154 case NodeResultInt52:155 type = m_out.int64;156 break;157 154 case NodeResultBoolean: 158 155 type = m_out.boolean; … … 243 240 break; 244 241 case JSConstant: 242 compileJSConstant(); 245 243 break; 246 244 case WeakJSConstant: … … 464 462 m_out.set(lowInt32(m_node->child1()), destination); 465 463 break; 466 case MachineIntUse:467 m_out.set(lowInt52(m_node->child1()), destination);468 break;469 464 case BooleanUse: 470 465 m_out.set(lowBoolean(m_node->child1()), destination); … … 492 487 case NodeResultInt32: 493 488 setInt32(m_out.get(source)); 494 break;495 case NodeResultInt52:496 setInt52(m_out.get(source));497 489 break; 498 490 case NodeResultBoolean: … … 600 592 } 601 593 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 609 594 case FlushedCell: { 610 595 LValue value = lowCell(m_node->child1()); … … 671 656 } 672 657 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 691 658 case NumberUse: { 692 659 setDouble( … … 716 683 speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1)); 717 684 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));736 685 break; 737 686 } … … 779 728 780 729 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);807 730 break; 808 731 } … … 1107 1030 1108 1031 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);1129 1032 break; 1130 1033 } … … 1571 1474 1572 1475 FTL_TYPE_CHECK( 1573 doubleValue(value), child3, Spec FullRealNumber,1476 doubleValue(value), child3, SpecRealNumber, 1574 1477 m_out.doubleNotEqualOrUnordered(value, value)); 1575 1478 … … 1806 1709 { 1807 1710 if (m_node->isBinaryUseKind(Int32Use) 1808 || m_node->isBinaryUseKind(MachineIntUse)1809 1711 || m_node->isBinaryUseKind(NumberUse) 1810 1712 || m_node->isBinaryUseKind(ObjectUse)) { … … 1830 1732 setBoolean( 1831 1733 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));1840 1734 return; 1841 1735 } … … 1889 1783 } 1890 1784 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 1899 1785 if (m_node->isBinaryUseKind(NumberUse)) { 1900 1786 setBoolean( … … 1911 1797 setBoolean( 1912 1798 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));1921 1799 return; 1922 1800 } … … 1940 1818 } 1941 1819 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 1950 1820 if (m_node->isBinaryUseKind(NumberUse)) { 1951 1821 setBoolean( … … 1964 1834 m_out.greaterThanOrEqual( 1965 1835 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));1974 1836 return; 1975 1837 } … … 2491 2353 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use)); 2492 2354 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 2502 2355 LoweredNodeValue value = m_int32Values.get(edge.node()); 2503 2356 if (isValid(value)) 2504 2357 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()));2513 2358 2514 2359 value = m_jsValueValues.get(edge.node()); … … 2527 2372 } 2528 2373 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 2632 2374 LValue lowCell(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) 2633 2375 { 2634 2376 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 }2644 2377 2645 2378 LoweredNodeValue value = m_jsValueValues.get(edge.node()); … … 2686 2419 { 2687 2420 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 }2697 2421 2698 2422 LoweredNodeValue value = m_booleanValues.get(edge.node()); … … 2719 2443 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind())); 2720 2444 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 2730 2445 LoweredNodeValue value = m_doubleValues.get(edge.node()); 2731 2446 if (isValid(value)) … … 2739 2454 } 2740 2455 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 2749 2456 value = m_jsValueValues.get(edge.node()); 2750 2457 if (isValid(value)) { … … 2766 2473 2767 2474 FTL_TYPE_CHECK( 2768 jsValueValue(boxedResult), edge, Spec FullNumber, isCellOrMisc(boxedResult));2475 jsValueValue(boxedResult), edge, SpecNumber, isCellOrMisc(boxedResult)); 2769 2476 2770 2477 ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedResult)); … … 2779 2486 } 2780 2487 2781 RELEASE_ASSERT(!(m_state.forNode(edge).m_type & Spec FullNumber));2488 RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecNumber)); 2782 2489 terminate(Uncountable); 2783 2490 return m_out.doubleZero; … … 2787 2494 { 2788 2495 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())));2792 2496 2793 2497 LoweredNodeValue value = m_jsValueValues.get(edge.node()); … … 2802 2506 } 2803 2507 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 2812 2508 value = m_booleanValues.get(edge.node()); 2813 2509 if (isValid(value)) { … … 2837 2533 setStorage(edge.node(), result); 2838 2534 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));2910 2535 } 2911 2536 … … 3170 2795 LValue value = lowDouble(edge); 3171 2796 FTL_TYPE_CHECK( 3172 doubleValue(value), edge, Spec FullRealNumber,2797 doubleValue(value), edge, SpecRealNumber, 3173 2798 m_out.doubleNotEqualOrUnordered(value, value)); 3174 2799 } … … 3178 2803 lowBoolean(edge); 3179 2804 } 3180 2805 3181 2806 bool masqueradesAsUndefinedWatchpointIsStillValid() 3182 2807 { … … 3309 2934 break; 3310 2935 3311 case FlushedInt52:3312 m_valueSources[i] = ValueSource(Int52InJSStack);3313 break;3314 3315 2936 case FlushedDouble: 3316 2937 m_valueSources[i] = ValueSource(DoubleInJSStack); … … 3415 3036 case Int32InJSStack: 3416 3037 exit.m_values[i] = ExitValue::inJSStackAsInt32(); 3417 break;3418 case Int52InJSStack:3419 exit.m_values[i] = ExitValue::inJSStackAsInt52();3420 3038 break; 3421 3039 case DoubleInJSStack: … … 3522 3140 } 3523 3141 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 3536 3142 value = m_booleanValues.get(node); 3537 3143 if (isValid(value)) { … … 3637 3243 m_int32Values.set(node, LoweredNodeValue(value, m_highBlock)); 3638 3244 } 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 }3661 3245 void setJSValue(Node* node, LValue value) 3662 3246 { … … 3679 3263 { 3680 3264 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);3693 3265 } 3694 3266 void setJSValue(LValue value) … … 3771 3343 3772 3344 HashMap<Node*, LoweredNodeValue> m_int32Values; 3773 HashMap<Node*, LoweredNodeValue> m_strictInt52Values;3774 HashMap<Node*, LoweredNodeValue> m_int52Values;3775 3345 HashMap<Node*, LoweredNodeValue> m_jsValueValues; 3776 3346 HashMap<Node*, LoweredNodeValue> m_booleanValues;
Note:
See TracChangeset
for help on using the changeset viewer.