| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +165 lines
Lines 1-5 a/Source/JavaScriptCore/ChangeLog_sec1
1
2017-04-27  Yusuke Suzuki  <utatane.tea@gmail.com>
1
2017-04-27  Yusuke Suzuki  <utatane.tea@gmail.com>
2
2
3
        [JSC] Math unary functions should be handled by DFG
4
        https://bugs.webkit.org/show_bug.cgi?id=171269
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        ArithSin, ArithCos, and ArithLog are just calling a C runtime function.
9
        While handling them in DFG is not very effective for performance, they
10
        can drop some type checks & value conversions and mark them as pure
11
        operations. It is effective if they are involved in some complex
12
        optimization phase. Actually, ArithLog is effective in kraken.
13
14
        While a few of Math functions have DFG nodes, basically math functions
15
        are pure. And large part of these functions are just calling a C runtime
16
        function. This patch generalizes these nodes in DFG as ArithUnary. And
17
        we annotate many unary math functions with Intrinsics and convert them
18
        to ArithUnary in DFG. It also cleans up duplicate code in ArithSin,
19
        ArithCos, and ArithLog. If your math function has some good DFG / FTL
20
        optimization rather than calling a C runtime function, you should add
21
        a specialized DFG node, like ArithSqrt.
22
23
        We also create a new namespace JSC::Math. Inside it, we collect math functions.
24
25
        * dfg/DFGAbstractInterpreterInlines.h:
26
        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
27
        * dfg/DFGArithMode.cpp:
28
        (JSC::DFG::arithUnaryFunction):
29
        (JSC::DFG::arithUnaryOperation):
30
        (WTF::printInternal):
31
        * dfg/DFGArithMode.h:
32
        * dfg/DFGBackwardsPropagationPhase.cpp:
33
        (JSC::DFG::BackwardsPropagationPhase::propagate):
34
        * dfg/DFGByteCodeParser.cpp:
35
        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
36
        * dfg/DFGClobberize.h:
37
        (JSC::DFG::clobberize):
38
        * dfg/DFGDoesGC.cpp:
39
        (JSC::DFG::doesGC):
40
        * dfg/DFGFixupPhase.cpp:
41
        (JSC::DFG::FixupPhase::fixupNode):
42
        * dfg/DFGGraph.cpp:
43
        (JSC::DFG::Graph::dump):
44
        * dfg/DFGNode.h:
45
        (JSC::DFG::Node::hasArithUnaryType):
46
        (JSC::DFG::Node::arithUnaryType):
47
        * dfg/DFGNodeType.h:
48
        * dfg/DFGOperations.cpp:
49
        * dfg/DFGOperations.h:
50
        * dfg/DFGPredictionPropagationPhase.cpp:
51
        * dfg/DFGSafeToExecute.h:
52
        (JSC::DFG::safeToExecute):
53
        * dfg/DFGSpeculativeJIT.cpp:
54
        (JSC::DFG::SpeculativeJIT::compileArithUnary):
55
        (JSC::DFG::SpeculativeJIT::compileArithCos): Deleted.
56
        (JSC::DFG::SpeculativeJIT::compileArithTan): Deleted.
57
        (JSC::DFG::SpeculativeJIT::compileArithSin): Deleted.
58
        (JSC::DFG::SpeculativeJIT::compileArithLog): Deleted.
59
        * dfg/DFGSpeculativeJIT.h:
60
        * dfg/DFGSpeculativeJIT32_64.cpp:
61
        (JSC::DFG::SpeculativeJIT::compile):
62
        * dfg/DFGSpeculativeJIT64.cpp:
63
        (JSC::DFG::SpeculativeJIT::compile):
64
        * ftl/FTLCapabilities.cpp:
65
        (JSC::FTL::canCompile):
66
        * ftl/FTLLowerDFGToB3.cpp:
67
        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
68
        (JSC::FTL::DFG::LowerDFGToB3::compileArithUnary):
69
        (JSC::FTL::DFG::LowerDFGToB3::compileArithSin): Deleted.
70
        (JSC::FTL::DFG::LowerDFGToB3::compileArithCos): Deleted.
71
        (JSC::FTL::DFG::LowerDFGToB3::compileArithTan): Deleted.
72
        (JSC::FTL::DFG::LowerDFGToB3::compileArithLog): Deleted.
73
        * ftl/FTLOutput.cpp:
74
        (JSC::FTL::Output::doubleUnary):
75
        (JSC::FTL::Output::doubleSin): Deleted.
76
        (JSC::FTL::Output::doubleCos): Deleted.
77
        (JSC::FTL::Output::doubleTan): Deleted.
78
        (JSC::FTL::Output::doubleLog): Deleted.
79
        * ftl/FTLOutput.h:
80
        * runtime/Intrinsic.h:
81
        * runtime/MathObject.cpp:
82
        (JSC::MathObject::finishCreation):
83
        (JSC::mathProtoFuncLog1p):
84
85
        * dfg/DFGAbstractInterpreterInlines.h:
86
        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
87
        * dfg/DFGArithMode.cpp:
88
        (JSC::DFG::arithUnaryFunction):
89
        (JSC::DFG::arithUnaryOperation):
90
        (WTF::printInternal):
91
        * dfg/DFGArithMode.h:
92
        * dfg/DFGBackwardsPropagationPhase.cpp:
93
        (JSC::DFG::BackwardsPropagationPhase::propagate):
94
        * dfg/DFGByteCodeParser.cpp:
95
        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
96
        * dfg/DFGClobberize.h:
97
        (JSC::DFG::clobberize):
98
        * dfg/DFGDoesGC.cpp:
99
        (JSC::DFG::doesGC):
100
        * dfg/DFGFixupPhase.cpp:
101
        (JSC::DFG::FixupPhase::fixupNode):
102
        * dfg/DFGGraph.cpp:
103
        (JSC::DFG::Graph::dump):
104
        * dfg/DFGNode.h:
105
        (JSC::DFG::Node::hasArithUnaryType):
106
        (JSC::DFG::Node::arithUnaryType):
107
        * dfg/DFGNodeType.h:
108
        * dfg/DFGOperations.cpp:
109
        * dfg/DFGOperations.h:
110
        * dfg/DFGPredictionPropagationPhase.cpp:
111
        * dfg/DFGSafeToExecute.h:
112
        (JSC::DFG::safeToExecute):
113
        * dfg/DFGSpeculativeJIT.cpp:
114
        (JSC::DFG::SpeculativeJIT::compileArithUnary):
115
        (JSC::DFG::SpeculativeJIT::compileArithCos): Deleted.
116
        (JSC::DFG::SpeculativeJIT::compileArithTan): Deleted.
117
        (JSC::DFG::SpeculativeJIT::compileArithSin): Deleted.
118
        (JSC::DFG::SpeculativeJIT::compileArithLog): Deleted.
119
        * dfg/DFGSpeculativeJIT.h:
120
        * dfg/DFGSpeculativeJIT32_64.cpp:
121
        (JSC::DFG::SpeculativeJIT::compile):
122
        * dfg/DFGSpeculativeJIT64.cpp:
123
        (JSC::DFG::SpeculativeJIT::compile):
124
        * ftl/FTLCapabilities.cpp:
125
        (JSC::FTL::canCompile):
126
        * ftl/FTLLowerDFGToB3.cpp:
127
        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
128
        (JSC::FTL::DFG::LowerDFGToB3::compileArithUnary):
129
        (JSC::FTL::DFG::LowerDFGToB3::compileArithSin): Deleted.
130
        (JSC::FTL::DFG::LowerDFGToB3::compileArithCos): Deleted.
131
        (JSC::FTL::DFG::LowerDFGToB3::compileArithTan): Deleted.
132
        (JSC::FTL::DFG::LowerDFGToB3::compileArithLog): Deleted.
133
        * ftl/FTLOutput.cpp:
134
        (JSC::FTL::Output::doubleUnary):
135
        (JSC::FTL::Output::doubleSin): Deleted.
136
        (JSC::FTL::Output::doubleCos): Deleted.
137
        (JSC::FTL::Output::doubleTan): Deleted.
138
        (JSC::FTL::Output::doubleLog): Deleted.
139
        * ftl/FTLOutput.h:
140
        * runtime/Intrinsic.h:
141
        * runtime/MathCommon.cpp:
142
        (JSC::Math::log1p):
143
        * runtime/MathCommon.h:
144
        * runtime/MathObject.cpp:
145
        (JSC::MathObject::finishCreation):
146
        (JSC::mathProtoFuncACos):
147
        (JSC::mathProtoFuncASin):
148
        (JSC::mathProtoFuncATan):
149
        (JSC::mathProtoFuncCos):
150
        (JSC::mathProtoFuncExp):
151
        (JSC::mathProtoFuncLog):
152
        (JSC::mathProtoFuncSin):
153
        (JSC::mathProtoFuncTan):
154
        (JSC::mathProtoFuncACosh):
155
        (JSC::mathProtoFuncASinh):
156
        (JSC::mathProtoFuncATanh):
157
        (JSC::mathProtoFuncCbrt):
158
        (JSC::mathProtoFuncCosh):
159
        (JSC::mathProtoFuncExpm1):
160
        (JSC::mathProtoFuncLog1p):
161
        (JSC::mathProtoFuncLog10):
162
        (JSC::mathProtoFuncLog2):
163
        (JSC::mathProtoFuncSinh):
164
        (JSC::mathProtoFuncTanh):
165
166
2017-04-27  Yusuke Suzuki  <utatane.tea@gmail.com>
167
3
        [JSC] Handle PhantomSpread in LoadVarargs as the same to the others
168
        [JSC] Handle PhantomSpread in LoadVarargs as the same to the others
4
        https://bugs.webkit.org/show_bug.cgi?id=171262
169
        https://bugs.webkit.org/show_bug.cgi?id=171262
5
170
- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h -14 / +2 lines
Lines 969-988 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec1
969
        executeDoubleUnaryOpEffects(node, [](double value) -> double { return static_cast<float>(value); });
969
        executeDoubleUnaryOpEffects(node, [](double value) -> double { return static_cast<float>(value); });
970
        break;
970
        break;
971
        
971
        
972
    case ArithSin:
972
    case ArithUnary:
973
        executeDoubleUnaryOpEffects(node, sin);
973
        executeDoubleUnaryOpEffects(node, arithUnaryFunction(node->arithUnaryType()));
974
        break;
975
    
976
    case ArithCos:
977
        executeDoubleUnaryOpEffects(node, cos);
978
        break;
979
980
    case ArithTan:
981
        executeDoubleUnaryOpEffects(node, tan);
982
        break;
983
984
    case ArithLog:
985
        executeDoubleUnaryOpEffects(node, log);
986
        break;
974
        break;
987
            
975
            
988
    case LogicalNot: {
976
    case LogicalNot: {
- a/Source/JavaScriptCore/dfg/DFGArithMode.cpp +44 lines
Lines 28-36 a/Source/JavaScriptCore/dfg/DFGArithMode.cpp_sec1
28
28
29
#if ENABLE(DFG_JIT)
29
#if ENABLE(DFG_JIT)
30
30
31
#include "DFGOperations.h"
31
#include "JSCInlines.h"
32
#include "JSCInlines.h"
32
#include <wtf/PrintStream.h>
33
#include <wtf/PrintStream.h>
33
34
35
namespace JSC { namespace DFG {
36
37
Arith::UnaryFunction arithUnaryFunction(Arith::UnaryType type)
38
{
39
    switch (type) {
40
#define DFG_ARITH_UNARY(capitalizedName, lowerName) \
41
    case Arith::UnaryType::capitalizedName: \
42
        return static_cast<Arith::UnaryFunction>(JSC::Math::lowerName);
43
    FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
44
#undef DFG_ARITH_UNARY
45
    }
46
    RELEASE_ASSERT_NOT_REACHED();
47
48
}
49
50
Arith::UnaryOperation arithUnaryOperation(Arith::UnaryType type)
51
{
52
    switch (type) {
53
#define DFG_ARITH_UNARY(capitalizedName, lowerName) \
54
    case Arith::UnaryType::capitalizedName: \
55
        return static_cast<Arith::UnaryOperation>(operationArith##capitalizedName);
56
    FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
57
#undef DFG_ARITH_UNARY
58
    }
59
    RELEASE_ASSERT_NOT_REACHED();
60
}
61
62
} } // namespace JSC::DFG
63
34
namespace WTF {
64
namespace WTF {
35
65
36
void printInternal(PrintStream& out, JSC::DFG::Arith::Mode mode)
66
void printInternal(PrintStream& out, JSC::DFG::Arith::Mode mode)
Lines 71-76 void printInternal(PrintStream& out, JSC::DFG::Arith::RoundingMode mode) a/Source/JavaScriptCore/dfg/DFGArithMode.cpp_sec2
71
    RELEASE_ASSERT_NOT_REACHED();
101
    RELEASE_ASSERT_NOT_REACHED();
72
}
102
}
73
103
104
void printInternal(PrintStream& out, JSC::DFG::Arith::UnaryType type)
105
{
106
    switch (type) {
107
#define DFG_ARITH_UNARY(capitalizedName, lowerName) \
108
    case JSC::DFG::Arith::UnaryType::capitalizedName: \
109
        out.print(#capitalizedName); \
110
        return;
111
    FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
112
#undef DFG_ARITH_UNARY
113
    }
114
    RELEASE_ASSERT_NOT_REACHED();
115
}
116
117
74
} // namespace WTF
118
} // namespace WTF
75
119
76
#endif // ENABLE(DFG_JIT)
120
#endif // ENABLE(DFG_JIT)
- a/Source/JavaScriptCore/dfg/DFGArithMode.h -1 / +42 lines
Lines 27-33 a/Source/JavaScriptCore/dfg/DFGArithMode.h_sec1
27
27
28
#if ENABLE(DFG_JIT)
28
#if ENABLE(DFG_JIT)
29
29
30
namespace JSC { namespace DFG {
30
namespace JSC {
31
32
class ExecState;
33
using EncodedJSValue = int64_t;
34
35
namespace DFG {
31
36
32
// Arith::Mode describes the mode of an arithmetic operation that speculates integer.
37
// Arith::Mode describes the mode of an arithmetic operation that speculates integer.
33
// Note that not all modes are valid for all operations.
38
// Note that not all modes are valid for all operations.
Lines 47-52 enum class RoundingMode { a/Source/JavaScriptCore/dfg/DFGArithMode.h_sec2
47
    Double // The round operation produce a double. The result can be -0, NaN or (+/-)Infinity.
52
    Double // The round operation produce a double. The result can be -0, NaN or (+/-)Infinity.
48
};
53
};
49
54
55
56
// This macro defines a set of information about all known arith unary generic node.
57
#define FOR_EACH_DFG_ARITH_UNARY_OP(macro) \
58
    macro(Sin, sin) \
59
    macro(Sinh, sinh) \
60
    macro(Cos, cos) \
61
    macro(Cosh, cosh) \
62
    macro(Tan, tan) \
63
    macro(Tanh, tanh) \
64
    macro(ASin, asin) \
65
    macro(ASinh, asinh) \
66
    macro(ACos, acos) \
67
    macro(ACosh, acosh) \
68
    macro(ATan, atan) \
69
    macro(ATanh, atanh) \
70
    macro(Log, log) \
71
    macro(Log10, log10) \
72
    macro(Log1p, log1p) \
73
    macro(Log2, log2) \
74
    macro(Cbrt, cbrt) \
75
    macro(Exp, exp) \
76
    macro(Expm1, expm1) \
77
78
enum class UnaryType : uint32_t {
79
#define DFG_ARITH_UNARY_ENUM(capitalizedName, lowerName) capitalizedName,
80
    FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY_ENUM)
81
#undef DFG_ARITH_UNARY_ENUM
82
};
83
84
typedef double (*UnaryFunction)(double);
85
typedef double (*UnaryOperation)(ExecState*, EncodedJSValue);
86
50
} // namespace Arith
87
} // namespace Arith
51
88
52
inline bool doesOverflow(Arith::Mode mode)
89
inline bool doesOverflow(Arith::Mode mode)
Lines 139-144 inline bool shouldCheckNegativeZero(Arith::RoundingMode mode) a/Source/JavaScriptCore/dfg/DFGArithMode.h_sec3
139
    return mode == Arith::RoundingMode::Int32WithNegativeZeroCheck;
176
    return mode == Arith::RoundingMode::Int32WithNegativeZeroCheck;
140
}
177
}
141
178
179
Arith::UnaryFunction arithUnaryFunction(Arith::UnaryType);
180
Arith::UnaryOperation arithUnaryOperation(Arith::UnaryType);
181
142
} } // namespace JSC::DFG
182
} } // namespace JSC::DFG
143
183
144
namespace WTF {
184
namespace WTF {
Lines 146-151 namespace WTF { a/Source/JavaScriptCore/dfg/DFGArithMode.h_sec4
146
class PrintStream;
186
class PrintStream;
147
void printInternal(PrintStream&, JSC::DFG::Arith::Mode);
187
void printInternal(PrintStream&, JSC::DFG::Arith::Mode);
148
void printInternal(PrintStream&, JSC::DFG::Arith::RoundingMode);
188
void printInternal(PrintStream&, JSC::DFG::Arith::RoundingMode);
189
void printInternal(PrintStream&, JSC::DFG::Arith::UnaryType);
149
190
150
} // namespace WTF
191
} // namespace WTF
151
192
- a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp -1 / +1 lines
Lines 411-417 class BackwardsPropagationPhase : public Phase { a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp_sec1
411
            RELEASE_ASSERT_NOT_REACHED();
411
            RELEASE_ASSERT_NOT_REACHED();
412
            break;
412
            break;
413
            
413
            
414
        // Note: ArithSqrt, ArithSin, and ArithCos and other math intrinsics don't have special
414
        // Note: ArithSqrt, ArithUnary and other math intrinsics don't have special
415
        // rules in here because they are always followed by Phantoms to signify that if the
415
        // rules in here because they are always followed by Phantoms to signify that if the
416
        // method call speculation fails, the bytecode may use the arguments in arbitrary ways.
416
        // method call speculation fails, the bytecode may use the arguments in arbitrary ways.
417
        // This corresponds to that possibility of someone doing something like:
417
        // This corresponds to that possibility of someone doing something like:
- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp -17 / +27 lines
Lines 2174-2185 bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrin a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec1
2174
    case MaxIntrinsic:
2174
    case MaxIntrinsic:
2175
        return handleMinMax(resultOperand, ArithMax, registerOffset, argumentCountIncludingThis, insertChecks);
2175
        return handleMinMax(resultOperand, ArithMax, registerOffset, argumentCountIncludingThis, insertChecks);
2176
2176
2177
    case CosIntrinsic:
2177
#define DFG_ARITH_UNARY(capitalizedName, lowerName) \
2178
    case capitalizedName##Intrinsic:
2179
    FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
2180
#undef DFG_ARITH_UNARY
2181
    {
2182
        if (argumentCountIncludingThis == 1) {
2183
            insertChecks();
2184
            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
2185
            return true;
2186
        }
2187
        Arith::UnaryType type = Arith::UnaryType::Sin;
2188
        switch (intrinsic) {
2189
#define DFG_ARITH_UNARY(capitalizedName, lowerName) \
2190
        case capitalizedName##Intrinsic: \
2191
            type = Arith::UnaryType::capitalizedName; \
2192
            break;
2193
    FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
2194
#undef DFG_ARITH_UNARY
2195
        default:
2196
            RELEASE_ASSERT_NOT_REACHED();
2197
        }
2198
        insertChecks();
2199
        set(VirtualRegister(resultOperand), addToGraph(ArithUnary, OpInfo(static_cast<std::underlying_type<Arith::UnaryType>::type>(type)), get(virtualRegisterForArgument(1, registerOffset))));
2200
        return true;
2201
    }
2202
2178
    case FRoundIntrinsic:
2203
    case FRoundIntrinsic:
2179
    case LogIntrinsic:
2204
    case SqrtIntrinsic: {
2180
    case SinIntrinsic:
2181
    case SqrtIntrinsic:
2182
    case TanIntrinsic: {
2183
        if (argumentCountIncludingThis == 1) {
2205
        if (argumentCountIncludingThis == 1) {
2184
            insertChecks();
2206
            insertChecks();
2185
            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
2207
            set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
Lines 2188-2211 bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrin a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec2
2188
2210
2189
        NodeType nodeType = Unreachable;
2211
        NodeType nodeType = Unreachable;
2190
        switch (intrinsic) {
2212
        switch (intrinsic) {
2191
        case CosIntrinsic:
2192
            nodeType = ArithCos;
2193
            break;
2194
        case FRoundIntrinsic:
2213
        case FRoundIntrinsic:
2195
            nodeType = ArithFRound;
2214
            nodeType = ArithFRound;
2196
            break;
2215
            break;
2197
        case LogIntrinsic:
2198
            nodeType = ArithLog;
2199
            break;
2200
        case SinIntrinsic:
2201
            nodeType = ArithSin;
2202
            break;
2203
        case SqrtIntrinsic:
2216
        case SqrtIntrinsic:
2204
            nodeType = ArithSqrt;
2217
            nodeType = ArithSqrt;
2205
            break;
2218
            break;
2206
        case TanIntrinsic:
2207
            nodeType = ArithTan;
2208
            break;
2209
        default:
2219
        default:
2210
            RELEASE_ASSERT_NOT_REACHED();
2220
            RELEASE_ASSERT_NOT_REACHED();
2211
        }
2221
        }
- a/Source/JavaScriptCore/dfg/DFGClobberize.h -4 / +9 lines
Lines 190-201 void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu a/Source/JavaScriptCore/dfg/DFGClobberize.h_sec1
190
        }
190
        }
191
        return;
191
        return;
192
        
192
        
193
    case ArithCos:
193
    case ArithUnary:
194
        if (node->child1().useKind() == DoubleRepUse)
195
            def(PureValue(node, static_cast<std::underlying_type<Arith::UnaryType>::type>(node->arithUnaryType())));
196
        else {
197
            read(World);
198
            write(Heap);
199
        }
200
        return;
201
194
    case ArithFRound:
202
    case ArithFRound:
195
    case ArithLog:
196
    case ArithSin:
197
    case ArithSqrt:
203
    case ArithSqrt:
198
    case ArithTan:
199
        if (node->child1().useKind() == DoubleRepUse)
204
        if (node->child1().useKind() == DoubleRepUse)
200
            def(PureValue(node));
205
            def(PureValue(node));
201
        else {
206
        else {
- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp -4 / +1 lines
Lines 92-101 bool doesGC(Graph& graph, Node* node) a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp_sec1
92
    case ArithCeil:
92
    case ArithCeil:
93
    case ArithTrunc:
93
    case ArithTrunc:
94
    case ArithFRound:
94
    case ArithFRound:
95
    case ArithSin:
95
    case ArithUnary:
96
    case ArithCos:
97
    case ArithTan:
98
    case ArithLog:
99
    case ValueAdd:
96
    case ValueAdd:
100
    case TryGetById:
97
    case TryGetById:
101
    case GetById:
98
    case GetById:
- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp -4 / +1 lines
Lines 427-438 class FixupPhase : public Phase { a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp_sec1
427
            break;
427
            break;
428
        }
428
        }
429
429
430
        case ArithCos:
431
        case ArithFRound:
430
        case ArithFRound:
432
        case ArithLog:
433
        case ArithSin:
434
        case ArithSqrt:
431
        case ArithSqrt:
435
        case ArithTan: {
432
        case ArithUnary: {
436
            Edge& child1 = node->child1();
433
            Edge& child1 = node->child1();
437
            if (child1->shouldSpeculateNotCell()) {
434
            if (child1->shouldSpeculateNotCell()) {
438
                fixDoubleOrBooleanEdge(child1);
435
                fixDoubleOrBooleanEdge(child1);
- a/Source/JavaScriptCore/dfg/DFGGraph.cpp +2 lines
Lines 232-237 void Graph::dump(PrintStream& out, const char* prefix, Node* node, DumpContext* a/Source/JavaScriptCore/dfg/DFGGraph.cpp_sec1
232
        out.print(comma, SpeculationDump(node->prediction()));
232
        out.print(comma, SpeculationDump(node->prediction()));
233
    if (node->hasArrayMode())
233
    if (node->hasArrayMode())
234
        out.print(comma, node->arrayMode());
234
        out.print(comma, node->arrayMode());
235
    if (node->hasArithUnaryType())
236
        out.print(comma, "Type:", node->arithUnaryType());
235
    if (node->hasArithMode())
237
    if (node->hasArithMode())
236
        out.print(comma, node->arithMode());
238
        out.print(comma, node->arithMode());
237
    if (node->hasArithRoundingMode())
239
    if (node->hasArithRoundingMode())
- a/Source/JavaScriptCore/dfg/DFGNode.h +11 lines
Lines 1891-1896 struct Node { a/Source/JavaScriptCore/dfg/DFGNode.h_sec1
1891
        ASSERT(hasArithRoundingMode());
1891
        ASSERT(hasArithRoundingMode());
1892
        m_opInfo = static_cast<uint32_t>(mode);
1892
        m_opInfo = static_cast<uint32_t>(mode);
1893
    }
1893
    }
1894
1895
    bool hasArithUnaryType()
1896
    {
1897
        return op() == ArithUnary;
1898
    }
1899
1900
    Arith::UnaryType arithUnaryType()
1901
    {
1902
        ASSERT(hasArithUnaryType());
1903
        return static_cast<Arith::UnaryType>(m_opInfo.as<uint32_t>());
1904
    }
1894
    
1905
    
1895
    bool hasVirtualRegister()
1906
    bool hasVirtualRegister()
1896
    {
1907
    {
- a/Source/JavaScriptCore/dfg/DFGNodeType.h -4 / +1 lines
Lines 159-168 namespace JSC { namespace DFG { a/Source/JavaScriptCore/dfg/DFGNodeType.h_sec1
159
    macro(ArithCeil, NodeResultNumber | NodeMustGenerate) \
159
    macro(ArithCeil, NodeResultNumber | NodeMustGenerate) \
160
    macro(ArithTrunc, NodeResultNumber | NodeMustGenerate) \
160
    macro(ArithTrunc, NodeResultNumber | NodeMustGenerate) \
161
    macro(ArithSqrt, NodeResultDouble | NodeMustGenerate) \
161
    macro(ArithSqrt, NodeResultDouble | NodeMustGenerate) \
162
    macro(ArithSin, NodeResultDouble | NodeMustGenerate) \
162
    macro(ArithUnary, NodeResultDouble | NodeMustGenerate) \
163
    macro(ArithCos, NodeResultDouble | NodeMustGenerate) \
164
    macro(ArithTan, NodeResultDouble | NodeMustGenerate) \
165
    macro(ArithLog, NodeResultDouble | NodeMustGenerate) \
166
    \
163
    \
167
    /* Add of values may either be arithmetic, or result in string concatenation. */\
164
    /* Add of values may either be arithmetic, or result in string concatenation. */\
168
    macro(ValueAdd, NodeResultJS | NodeMustGenerate) \
165
    macro(ValueAdd, NodeResultJS | NodeMustGenerate) \
- a/Source/JavaScriptCore/dfg/DFGOperations.cpp -46 / +12 lines
Lines 384-401 int32_t JIT_OPERATION operationArithClz32(ExecState* exec, EncodedJSValue encode a/Source/JavaScriptCore/dfg/DFGOperations.cpp_sec1
384
    return clz32(value);
384
    return clz32(value);
385
}
385
}
386
386
387
double JIT_OPERATION operationArithCos(ExecState* exec, EncodedJSValue encodedOp1)
388
{
389
    VM* vm = &exec->vm();
390
    NativeCallFrameTracer tracer(vm, exec);
391
    auto scope = DECLARE_THROW_SCOPE(*vm);
392
393
    JSValue op1 = JSValue::decode(encodedOp1);
394
    double a = op1.toNumber(exec);
395
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
396
    return cos(a);
397
}
398
399
double JIT_OPERATION operationArithFRound(ExecState* exec, EncodedJSValue encodedOp1)
387
double JIT_OPERATION operationArithFRound(ExecState* exec, EncodedJSValue encodedOp1)
400
{
388
{
401
    VM* vm = &exec->vm();
389
    VM* vm = &exec->vm();
Lines 408-436 double JIT_OPERATION operationArithFRound(ExecState* exec, EncodedJSValue encode a/Source/JavaScriptCore/dfg/DFGOperations.cpp_sec2
408
    return static_cast<float>(a);
396
    return static_cast<float>(a);
409
}
397
}
410
398
411
double JIT_OPERATION operationArithLog(ExecState* exec, EncodedJSValue encodedOp1)
399
#define DFG_ARITH_UNARY(capitalizedName, lowerName) \
412
{
400
double JIT_OPERATION operationArith##capitalizedName(ExecState* exec, EncodedJSValue encodedOp1) \
413
    VM* vm = &exec->vm();
401
{ \
414
    NativeCallFrameTracer tracer(vm, exec);
402
    VM* vm = &exec->vm(); \
415
    auto scope = DECLARE_THROW_SCOPE(*vm);
403
    NativeCallFrameTracer tracer(vm, exec); \
416
404
    auto scope = DECLARE_THROW_SCOPE(*vm); \
417
    JSValue op1 = JSValue::decode(encodedOp1);
405
    JSValue op1 = JSValue::decode(encodedOp1); \
418
    double a = op1.toNumber(exec);
406
    double a = op1.toNumber(exec); \
419
    RETURN_IF_EXCEPTION(scope, PNaN);
407
    RETURN_IF_EXCEPTION(scope, PNaN); \
420
    return log(a);
408
    return lowerName(a); \
421
}
422
423
double JIT_OPERATION operationArithSin(ExecState* exec, EncodedJSValue encodedOp1)
424
{
425
    VM* vm = &exec->vm();
426
    NativeCallFrameTracer tracer(vm, exec);
427
    auto scope = DECLARE_THROW_SCOPE(*vm);
428
429
    JSValue op1 = JSValue::decode(encodedOp1);
430
    double a = op1.toNumber(exec);
431
    RETURN_IF_EXCEPTION(scope, PNaN);
432
    return sin(a);
433
}
409
}
410
    FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
411
#undef DFG_ARITH_UNARY
434
412
435
double JIT_OPERATION operationArithSqrt(ExecState* exec, EncodedJSValue encodedOp1)
413
double JIT_OPERATION operationArithSqrt(ExecState* exec, EncodedJSValue encodedOp1)
436
{
414
{
Lines 444-461 double JIT_OPERATION operationArithSqrt(ExecState* exec, EncodedJSValue encodedO a/Source/JavaScriptCore/dfg/DFGOperations.cpp_sec3
444
    return sqrt(a);
422
    return sqrt(a);
445
}
423
}
446
424
447
double JIT_OPERATION operationArithTan(ExecState* exec, EncodedJSValue encodedOp1)
448
{
449
    VM* vm = &exec->vm();
450
    NativeCallFrameTracer tracer(vm, exec);
451
    auto scope = DECLARE_THROW_SCOPE(*vm);
452
453
    JSValue op1 = JSValue::decode(encodedOp1);
454
    double a = op1.toNumber(exec);
455
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
456
    return tan(a);
457
}
458
459
EncodedJSValue JIT_OPERATION operationArithRound(ExecState* exec, EncodedJSValue encodedArgument)
425
EncodedJSValue JIT_OPERATION operationArithRound(ExecState* exec, EncodedJSValue encodedArgument)
460
{
426
{
461
    VM* vm = &exec->vm();
427
    VM* vm = &exec->vm();
- a/Source/JavaScriptCore/dfg/DFGOperations.h -4 / +7 lines
Lines 27-32 a/Source/JavaScriptCore/dfg/DFGOperations.h_sec1
27
27
28
#if ENABLE(DFG_JIT)
28
#if ENABLE(DFG_JIT)
29
29
30
#include "DFGArithMode.h"
30
#include "JITOperations.h"
31
#include "JITOperations.h"
31
#include "PutKind.h"
32
#include "PutKind.h"
32
33
Lines 54-65 EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState*, EncodedJSVal a/Source/JavaScriptCore/dfg/DFGOperations.h_sec2
54
EncodedJSValue JIT_OPERATION operationValueDiv(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
55
EncodedJSValue JIT_OPERATION operationValueDiv(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
55
double JIT_OPERATION operationArithAbs(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
56
double JIT_OPERATION operationArithAbs(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
56
int32_t JIT_OPERATION operationArithClz32(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
57
int32_t JIT_OPERATION operationArithClz32(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
57
double JIT_OPERATION operationArithCos(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
58
double JIT_OPERATION operationArithTan(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
59
double JIT_OPERATION operationArithFRound(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
58
double JIT_OPERATION operationArithFRound(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
60
double JIT_OPERATION operationArithLog(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
61
double JIT_OPERATION operationArithSin(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
62
double JIT_OPERATION operationArithSqrt(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
59
double JIT_OPERATION operationArithSqrt(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
60
61
#define DFG_ARITH_UNARY(capitalizedName, lowerName) \
62
double JIT_OPERATION operationArith##capitalizedName(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
63
    FOR_EACH_DFG_ARITH_UNARY_OP(DFG_ARITH_UNARY)
64
#undef DFG_ARITH_UNARY
65
63
EncodedJSValue JIT_OPERATION operationArithRound(ExecState*, EncodedJSValue) WTF_INTERNAL;
66
EncodedJSValue JIT_OPERATION operationArithRound(ExecState*, EncodedJSValue) WTF_INTERNAL;
64
EncodedJSValue JIT_OPERATION operationArithFloor(ExecState*, EncodedJSValue) WTF_INTERNAL;
67
EncodedJSValue JIT_OPERATION operationArithFloor(ExecState*, EncodedJSValue) WTF_INTERNAL;
65
EncodedJSValue JIT_OPERATION operationArithCeil(ExecState*, EncodedJSValue) WTF_INTERNAL;
68
EncodedJSValue JIT_OPERATION operationArithCeil(ExecState*, EncodedJSValue) WTF_INTERNAL;
- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp -8 / +2 lines
Lines 567-576 class PredictionPropagationPhase : public Phase { a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp_sec1
567
            break;
567
            break;
568
                
568
                
569
        case ArithSqrt:
569
        case ArithSqrt:
570
        case ArithCos:
570
        case ArithUnary:
571
        case ArithSin:
572
        case ArithTan:
573
        case ArithLog:
574
            if (node->child1()->shouldSpeculateNumber())
571
            if (node->child1()->shouldSpeculateNumber())
575
                m_graph.voteNode(node->child1(), VoteDouble, weight);
572
                m_graph.voteNode(node->child1(), VoteDouble, weight);
576
            else
573
            else
Lines 787-796 class PredictionPropagationPhase : public Phase { a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp_sec2
787
        case ArithPow:
784
        case ArithPow:
788
        case ArithSqrt:
785
        case ArithSqrt:
789
        case ArithFRound:
786
        case ArithFRound:
790
        case ArithSin:
787
        case ArithUnary: {
791
        case ArithCos:
792
        case ArithTan:
793
        case ArithLog: {
794
            setPrediction(SpecBytecodeDouble);
788
            setPrediction(SpecBytecodeDouble);
795
            break;
789
            break;
796
        }
790
        }
- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h -4 / +1 lines
Lines 191-200 bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node) a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h_sec1
191
    case ArithFloor:
191
    case ArithFloor:
192
    case ArithCeil:
192
    case ArithCeil:
193
    case ArithTrunc:
193
    case ArithTrunc:
194
    case ArithSin:
194
    case ArithUnary:
195
    case ArithCos:
196
    case ArithTan:
197
    case ArithLog:
198
    case ValueAdd:
195
    case ValueAdd:
199
    case TryGetById:
196
    case TryGetById:
200
    case DeleteById:
197
    case DeleteById:
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp -17 / +2 lines
Lines 4151-4166 void SpeculativeJIT::compileArithDoubleUnaryOp(Node* node, double (*doubleFuncti a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec1
4151
    doubleResult(result.fpr(), node);
4151
    doubleResult(result.fpr(), node);
4152
}
4152
}
4153
4153
4154
void SpeculativeJIT::compileArithCos(Node* node)
4155
{
4156
    compileArithDoubleUnaryOp(node, cos, operationArithCos);
4157
}
4158
4159
void SpeculativeJIT::compileArithTan(Node* node)
4160
{
4161
    compileArithDoubleUnaryOp(node, tan, operationArithTan);
4162
}
4163
4164
void SpeculativeJIT::compileArithSub(Node* node)
4154
void SpeculativeJIT::compileArithSub(Node* node)
4165
{
4155
{
4166
    switch (node->binaryUseKind()) {
4156
    switch (node->binaryUseKind()) {
Lines 5313-5321 void SpeculativeJIT::compileArithRounding(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec2
5313
    jsValueResult(resultRegs, node);
5303
    jsValueResult(resultRegs, node);
5314
}
5304
}
5315
5305
5316
void SpeculativeJIT::compileArithSin(Node* node)
5306
void SpeculativeJIT::compileArithUnary(Node* node)
5317
{
5307
{
5318
    compileArithDoubleUnaryOp(node, sin, operationArithSin);
5308
    compileArithDoubleUnaryOp(node, arithUnaryFunction(node->arithUnaryType()), arithUnaryOperation(node->arithUnaryType()));
5319
}
5309
}
5320
5310
5321
void SpeculativeJIT::compileArithSqrt(Node* node)
5311
void SpeculativeJIT::compileArithSqrt(Node* node)
Lines 5494-5504 void SpeculativeJIT::compileArithPow(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec3
5494
    doubleResult(resultFpr, node);
5484
    doubleResult(resultFpr, node);
5495
}
5485
}
5496
5486
5497
void SpeculativeJIT::compileArithLog(Node* node)
5498
{
5499
    compileArithDoubleUnaryOp(node, log, operationArithLog);
5500
}
5501
5502
// Returns true if the compare is fused with a subsequent branch.
5487
// Returns true if the compare is fused with a subsequent branch.
5503
bool SpeculativeJIT::compare(Node* node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_JITOperation_EJJ operation)
5488
bool SpeculativeJIT::compare(Node* node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_JITOperation_EJJ operation)
5504
{
5489
{
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h -4 / +1 lines
Lines 2802-2809 class SpeculativeJIT { a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h_sec1
2802
    void compileMakeRope(Node*);
2802
    void compileMakeRope(Node*);
2803
    void compileArithAbs(Node*);
2803
    void compileArithAbs(Node*);
2804
    void compileArithClz32(Node*);
2804
    void compileArithClz32(Node*);
2805
    void compileArithCos(Node*);
2806
    void compileArithTan(Node*);
2807
    void compileArithSub(Node*);
2805
    void compileArithSub(Node*);
2808
    void compileArithNegate(Node*);
2806
    void compileArithNegate(Node*);
2809
    void compileArithMul(Node*);
2807
    void compileArithMul(Node*);
Lines 2813-2821 class SpeculativeJIT { a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h_sec2
2813
    void compileArithPow(Node*);
2811
    void compileArithPow(Node*);
2814
    void compileArithRounding(Node*);
2812
    void compileArithRounding(Node*);
2815
    void compileArithRandom(Node*);
2813
    void compileArithRandom(Node*);
2816
    void compileArithSin(Node*);
2814
    void compileArithUnary(Node*);
2817
    void compileArithSqrt(Node*);
2815
    void compileArithSqrt(Node*);
2818
    void compileArithLog(Node*);
2819
    void compileConstantStoragePointer(Node*);
2816
    void compileConstantStoragePointer(Node*);
2820
    void compileGetIndexedPropertyStorage(Node*);
2817
    void compileGetIndexedPropertyStorage(Node*);
2821
    JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
2818
    JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp -14 / +2 lines
Lines 2479-2498 void SpeculativeJIT::compile(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp_sec1
2479
        compileArithRounding(node);
2479
        compileArithRounding(node);
2480
        break;
2480
        break;
2481
2481
2482
    case ArithSin:
2482
    case ArithUnary:
2483
        compileArithSin(node);
2483
        compileArithUnary(node);
2484
        break;
2485
2486
    case ArithCos:
2487
        compileArithCos(node);
2488
        break;
2489
2490
    case ArithTan:
2491
        compileArithTan(node);
2492
        break;
2493
2494
    case ArithLog:
2495
        compileArithLog(node);
2496
        break;
2484
        break;
2497
2485
2498
    case LogicalNot:
2486
    case LogicalNot:
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp -14 / +2 lines
Lines 2627-2646 void SpeculativeJIT::compile(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp_sec1
2627
        compileArithRounding(node);
2627
        compileArithRounding(node);
2628
        break;
2628
        break;
2629
2629
2630
    case ArithSin:
2630
    case ArithUnary:
2631
        compileArithSin(node);
2631
        compileArithUnary(node);
2632
        break;
2633
2634
    case ArithCos:
2635
        compileArithCos(node);
2636
        break;
2637
2638
    case ArithTan:
2639
        compileArithTan(node);
2640
        break;
2641
2642
    case ArithLog:
2643
        compileArithLog(node);
2644
        break;
2632
        break;
2645
2633
2646
    case LogicalNot:
2634
    case LogicalNot:
- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp -4 / +1 lines
Lines 94-102 inline CapabilityLevel canCompile(Node* node) a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp_sec1
94
    case ArithMin:
94
    case ArithMin:
95
    case ArithMax:
95
    case ArithMax:
96
    case ArithAbs:
96
    case ArithAbs:
97
    case ArithSin:
98
    case ArithCos:
99
    case ArithTan:
100
    case ArithPow:
97
    case ArithPow:
101
    case ArithRandom:
98
    case ArithRandom:
102
    case ArithRound:
99
    case ArithRound:
Lines 104-112 inline CapabilityLevel canCompile(Node* node) a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp_sec2
104
    case ArithCeil:
101
    case ArithCeil:
105
    case ArithTrunc:
102
    case ArithTrunc:
106
    case ArithSqrt:
103
    case ArithSqrt:
107
    case ArithLog:
108
    case ArithFRound:
104
    case ArithFRound:
109
    case ArithNegate:
105
    case ArithNegate:
106
    case ArithUnary:
110
    case UInt32ToNumber:
107
    case UInt32ToNumber:
111
    case Jump:
108
    case Jump:
112
    case ForceOSRExit:
109
    case ForceOSRExit:
- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp -48 / +6 lines
Lines 545-559 class LowerDFGToB3 { a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec1
545
        case ArithAbs:
545
        case ArithAbs:
546
            compileArithAbs();
546
            compileArithAbs();
547
            break;
547
            break;
548
        case ArithSin:
549
            compileArithSin();
550
            break;
551
        case ArithCos:
552
            compileArithCos();
553
            break;
554
        case ArithTan:
555
            compileArithTan();
556
            break;
557
        case ArithPow:
548
        case ArithPow:
558
            compileArithPow();
549
            compileArithPow();
559
            break;
550
            break;
Lines 575-589 class LowerDFGToB3 { a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec2
575
        case ArithSqrt:
566
        case ArithSqrt:
576
            compileArithSqrt();
567
            compileArithSqrt();
577
            break;
568
            break;
578
        case ArithLog:
579
            compileArithLog();
580
            break;
581
        case ArithFRound:
569
        case ArithFRound:
582
            compileArithFRound();
570
            compileArithFRound();
583
            break;
571
            break;
584
        case ArithNegate:
572
        case ArithNegate:
585
            compileArithNegate();
573
            compileArithNegate();
586
            break;
574
            break;
575
        case ArithUnary:
576
            compileArithUnary();
577
            break;
587
        case DFG::BitAnd:
578
        case DFG::BitAnd:
588
            compileBitAnd();
579
            compileBitAnd();
589
            break;
580
            break;
Lines 2207-2242 class LowerDFGToB3 { a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec3
2207
        }
2198
        }
2208
    }
2199
    }
2209
2200
2210
    void compileArithSin()
2201
    void compileArithUnary()
2211
    {
2202
    {
2212
        if (m_node->child1().useKind() == DoubleRepUse) {
2203
        if (m_node->child1().useKind() == DoubleRepUse) {
2213
            setDouble(m_out.doubleSin(lowDouble(m_node->child1())));
2204
            setDouble(m_out.doubleUnary(m_node->arithUnaryType(), lowDouble(m_node->child1())));
2214
            return;
2205
            return;
2215
        }
2206
        }
2216
        LValue argument = lowJSValue(m_node->child1());
2207
        LValue argument = lowJSValue(m_node->child1());
2217
        LValue result = vmCall(Double, m_out.operation(operationArithSin), m_callFrame, argument);
2208
        LValue result = vmCall(Double, m_out.operation(DFG::arithUnaryOperation(m_node->arithUnaryType())), m_callFrame, argument);
2218
        setDouble(result);
2219
    }
2220
2221
    void compileArithCos()
2222
    {
2223
        if (m_node->child1().useKind() == DoubleRepUse) {
2224
            setDouble(m_out.doubleCos(lowDouble(m_node->child1())));
2225
            return;
2226
        }
2227
        LValue argument = lowJSValue(m_node->child1());
2228
        LValue result = vmCall(Double, m_out.operation(operationArithCos), m_callFrame, argument);
2229
        setDouble(result);
2230
    }
2231
2232
    void compileArithTan()
2233
    {
2234
        if (m_node->child1().useKind() == DoubleRepUse) {
2235
            setDouble(m_out.doubleTan(lowDouble(m_node->child1())));
2236
            return;
2237
        }
2238
        LValue argument = lowJSValue(m_node->child1());
2239
        LValue result = vmCall(Double, m_out.operation(operationArithTan), m_callFrame, argument);
2240
        setDouble(result);
2209
        setDouble(result);
2241
    }
2210
    }
2242
2211
Lines 2524-2540 class LowerDFGToB3 { a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec4
2524
        setDouble(result);
2493
        setDouble(result);
2525
    }
2494
    }
2526
2495
2527
    void compileArithLog()
2528
    {
2529
        if (m_node->child1().useKind() == DoubleRepUse) {
2530
            setDouble(m_out.doubleLog(lowDouble(m_node->child1())));
2531
            return;
2532
        }
2533
        LValue argument = lowJSValue(m_node->child1());
2534
        LValue result = vmCall(Double, m_out.operation(operationArithLog), m_callFrame, argument);
2535
        setDouble(result);
2536
    }
2537
    
2538
    void compileArithFRound()
2496
    void compileArithFRound()
2539
    {
2497
    {
2540
        if (m_node->child1().useKind() == DoubleRepUse) {
2498
        if (m_node->child1().useKind() == DoubleRepUse) {
- a/Source/JavaScriptCore/ftl/FTLOutput.cpp -21 / +3 lines
Lines 289-310 LValue Output::doubleTrunc(LValue value) a/Source/JavaScriptCore/ftl/FTLOutput.cpp_sec1
289
    return callWithoutSideEffects(Double, truncDouble, value);
289
    return callWithoutSideEffects(Double, truncDouble, value);
290
}
290
}
291
291
292
LValue Output::doubleSin(LValue value)
292
LValue Output::doubleUnary(DFG::Arith::UnaryType type, LValue value)
293
{
293
{
294
    double (*sinDouble)(double) = sin;
294
    double (*unaryFunction)(double) = DFG::arithUnaryFunction(type);
295
    return callWithoutSideEffects(B3::Double, sinDouble, value);
295
    return callWithoutSideEffects(B3::Double, unaryFunction, value);
296
}
297
298
LValue Output::doubleCos(LValue value)
299
{
300
    double (*cosDouble)(double) = cos;
301
    return callWithoutSideEffects(B3::Double, cosDouble, value);
302
}
303
304
LValue Output::doubleTan(LValue value)
305
{
306
    double (*tanDouble)(double) = tan;
307
    return callWithoutSideEffects(B3::Double, tanDouble, value);
308
}
296
}
309
297
310
LValue Output::doublePow(LValue xOperand, LValue yOperand)
298
LValue Output::doublePow(LValue xOperand, LValue yOperand)
Lines 328-339 LValue Output::doubleSqrt(LValue value) a/Source/JavaScriptCore/ftl/FTLOutput.cpp_sec2
328
    return m_block->appendNew<B3::Value>(m_proc, B3::Sqrt, origin(), value);
316
    return m_block->appendNew<B3::Value>(m_proc, B3::Sqrt, origin(), value);
329
}
317
}
330
318
331
LValue Output::doubleLog(LValue value)
332
{
333
    double (*logDouble)(double) = log;
334
    return callWithoutSideEffects(B3::Double, logDouble, value);
335
}
336
337
LValue Output::doubleToInt(LValue value)
319
LValue Output::doubleToInt(LValue value)
338
{
320
{
339
    PatchpointValue* result = patchpoint(Int32);
321
    PatchpointValue* result = patchpoint(Int32);
- a/Source/JavaScriptCore/ftl/FTLOutput.h -3 / +1 lines
Lines 183-191 class Output : public CommonValues { a/Source/JavaScriptCore/ftl/FTLOutput.h_sec1
183
    LValue doubleFloor(LValue);
183
    LValue doubleFloor(LValue);
184
    LValue doubleTrunc(LValue);
184
    LValue doubleTrunc(LValue);
185
185
186
    LValue doubleSin(LValue);
186
    LValue doubleUnary(DFG::Arith::UnaryType, LValue);
187
    LValue doubleCos(LValue);
188
    LValue doubleTan(LValue);
189
187
190
    LValue doublePow(LValue base, LValue exponent);
188
    LValue doublePow(LValue base, LValue exponent);
191
    LValue doublePowi(LValue base, LValue exponent);
189
    LValue doublePowi(LValue base, LValue exponent);
- a/Source/JavaScriptCore/runtime/Intrinsic.h +14 lines
Lines 31-43 enum JS_EXPORT_PRIVATE Intrinsic { a/Source/JavaScriptCore/runtime/Intrinsic.h_sec1
31
    // Call intrinsics.
31
    // Call intrinsics.
32
    NoIntrinsic,
32
    NoIntrinsic,
33
    AbsIntrinsic,
33
    AbsIntrinsic,
34
    ACosIntrinsic,
35
    ASinIntrinsic,
36
    ATanIntrinsic,
37
    ACoshIntrinsic,
38
    ASinhIntrinsic,
39
    ATanhIntrinsic,
34
    MinIntrinsic,
40
    MinIntrinsic,
35
    MaxIntrinsic,
41
    MaxIntrinsic,
36
    SqrtIntrinsic,
42
    SqrtIntrinsic,
37
    SinIntrinsic,
43
    SinIntrinsic,
44
    CbrtIntrinsic,
38
    Clz32Intrinsic,
45
    Clz32Intrinsic,
39
    CosIntrinsic,
46
    CosIntrinsic,
40
    TanIntrinsic,
47
    TanIntrinsic,
48
    CoshIntrinsic,
49
    SinhIntrinsic,
50
    TanhIntrinsic,
41
    ArrayPushIntrinsic,
51
    ArrayPushIntrinsic,
42
    ArrayPopIntrinsic,
52
    ArrayPopIntrinsic,
43
    ArraySliceIntrinsic,
53
    ArraySliceIntrinsic,
Lines 49-55 enum JS_EXPORT_PRIVATE Intrinsic { a/Source/JavaScriptCore/runtime/Intrinsic.h_sec2
49
    CeilIntrinsic,
59
    CeilIntrinsic,
50
    RoundIntrinsic,
60
    RoundIntrinsic,
51
    ExpIntrinsic,
61
    ExpIntrinsic,
62
    Expm1Intrinsic,
52
    LogIntrinsic,
63
    LogIntrinsic,
64
    Log10Intrinsic,
65
    Log1pIntrinsic,
66
    Log2Intrinsic,
53
    RegExpExecIntrinsic,
67
    RegExpExecIntrinsic,
54
    RegExpTestIntrinsic,
68
    RegExpTestIntrinsic,
55
    RegExpTestFastIntrinsic,
69
    RegExpTestFastIntrinsic,
- a/Source/JavaScriptCore/runtime/MathCommon.cpp +10 lines
Lines 521-524 double jsMod(double x, double y) a/Source/JavaScriptCore/runtime/MathCommon.cpp_sec1
521
#endif
521
#endif
522
} // extern "C"
522
} // extern "C"
523
523
524
namespace Math {
525
526
extern "C" double JIT_OPERATION log1p(double value)
527
{
528
    if (!value)
529
        return value;
530
    return ::log1p(value);
531
}
532
533
} // namespace Math
524
} // namespace JSC
534
} // namespace JSC
- a/Source/JavaScriptCore/runtime/MathCommon.h +24 lines
Lines 209-212 double JIT_OPERATION jsMod(double x, double y) REFERENCED_FROM_ASM WTF_INTERNAL; a/Source/JavaScriptCore/runtime/MathCommon.h_sec1
209
#endif
209
#endif
210
}
210
}
211
211
212
namespace Math {
213
214
using ::sin;
215
using ::sinh;
216
using ::cos;
217
using ::cosh;
218
using ::tan;
219
using ::tanh;
220
using ::asin;
221
using ::asinh;
222
using ::acos;
223
using ::acosh;
224
using ::atan;
225
using ::atanh;
226
using ::log;
227
using ::log10;
228
using ::log2;
229
using ::cbrt;
230
using ::exp;
231
using ::expm1;
232
233
extern "C" JIT_OPERATION double log1p(double) WTF_INTERNAL;
234
235
} // namespace Math
212
} // namespace JSC
236
} // namespace JSC
- a/Source/JavaScriptCore/runtime/MathObject.cpp -40 / +37 lines
Lines 78-87 void MathObject::finishCreation(VM& vm, JSGlobalObject* globalObject) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec1
78
    Base::finishCreation(vm);
78
    Base::finishCreation(vm);
79
    ASSERT(inherits(vm, info()));
79
    ASSERT(inherits(vm, info()));
80
80
81
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "E"), jsNumber(exp(1.0)), DontDelete | DontEnum | ReadOnly);
81
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "E"), jsNumber(Math::exp(1.0)), DontDelete | DontEnum | ReadOnly);
82
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LN2"), jsNumber(log(2.0)), DontDelete | DontEnum | ReadOnly);
82
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LN2"), jsNumber(Math::log(2.0)), DontDelete | DontEnum | ReadOnly);
83
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LN10"), jsNumber(log(10.0)), DontDelete | DontEnum | ReadOnly);
83
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LN10"), jsNumber(Math::log(10.0)), DontDelete | DontEnum | ReadOnly);
84
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LOG2E"), jsNumber(1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly);
84
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LOG2E"), jsNumber(1.0 / Math::log(2.0)), DontDelete | DontEnum | ReadOnly);
85
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LOG10E"), jsNumber(0.4342944819032518), DontDelete | DontEnum | ReadOnly);
85
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "LOG10E"), jsNumber(0.4342944819032518), DontDelete | DontEnum | ReadOnly);
86
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "PI"), jsNumber(piDouble), DontDelete | DontEnum | ReadOnly);
86
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "PI"), jsNumber(piDouble), DontDelete | DontEnum | ReadOnly);
87
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "SQRT1_2"), jsNumber(sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
87
    putDirectWithoutTransition(vm, Identifier::fromString(&vm, "SQRT1_2"), jsNumber(sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
Lines 89-115 void MathObject::finishCreation(VM& vm, JSGlobalObject* globalObject) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec2
89
    putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Math"), DontEnum | ReadOnly);
89
    putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Math"), DontEnum | ReadOnly);
90
90
91
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "abs"), 1, mathProtoFuncAbs, AbsIntrinsic, DontEnum);
91
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "abs"), 1, mathProtoFuncAbs, AbsIntrinsic, DontEnum);
92
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "acos"), 1, mathProtoFuncACos, NoIntrinsic, DontEnum);
92
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "acos"), 1, mathProtoFuncACos, ACosIntrinsic, DontEnum);
93
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "asin"), 1, mathProtoFuncASin, NoIntrinsic, DontEnum);
93
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "asin"), 1, mathProtoFuncASin, ASinIntrinsic, DontEnum);
94
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "atan"), 1, mathProtoFuncATan, NoIntrinsic, DontEnum);
94
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "atan"), 1, mathProtoFuncATan, ATanIntrinsic, DontEnum);
95
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "acosh"), 1, mathProtoFuncACosh, NoIntrinsic, DontEnum);
95
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "acosh"), 1, mathProtoFuncACosh, ACoshIntrinsic, DontEnum);
96
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "asinh"), 1, mathProtoFuncASinh, NoIntrinsic, DontEnum);
96
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "asinh"), 1, mathProtoFuncASinh, ASinhIntrinsic, DontEnum);
97
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "atanh"), 1, mathProtoFuncATanh, NoIntrinsic, DontEnum);
97
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "atanh"), 1, mathProtoFuncATanh, ATanhIntrinsic, DontEnum);
98
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "atan2"), 2, mathProtoFuncATan2, NoIntrinsic, DontEnum);
98
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "atan2"), 2, mathProtoFuncATan2, NoIntrinsic, DontEnum);
99
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "cbrt"), 1, mathProtoFuncCbrt, NoIntrinsic, DontEnum);
99
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "cbrt"), 1, mathProtoFuncCbrt, CbrtIntrinsic, DontEnum);
100
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "ceil"), 1, mathProtoFuncCeil, CeilIntrinsic, DontEnum);
100
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "ceil"), 1, mathProtoFuncCeil, CeilIntrinsic, DontEnum);
101
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "clz32"), 1, mathProtoFuncClz32, Clz32Intrinsic, DontEnum);
101
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "clz32"), 1, mathProtoFuncClz32, Clz32Intrinsic, DontEnum);
102
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "cos"), 1, mathProtoFuncCos, CosIntrinsic, DontEnum);
102
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "cos"), 1, mathProtoFuncCos, CosIntrinsic, DontEnum);
103
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "cosh"), 1, mathProtoFuncCosh, NoIntrinsic, DontEnum);
103
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "cosh"), 1, mathProtoFuncCosh, CoshIntrinsic, DontEnum);
104
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "exp"), 1, mathProtoFuncExp, ExpIntrinsic, DontEnum);
104
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "exp"), 1, mathProtoFuncExp, ExpIntrinsic, DontEnum);
105
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "expm1"), 1, mathProtoFuncExpm1, NoIntrinsic, DontEnum);
105
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "expm1"), 1, mathProtoFuncExpm1, Expm1Intrinsic, DontEnum);
106
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "floor"), 1, mathProtoFuncFloor, FloorIntrinsic, DontEnum);
106
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "floor"), 1, mathProtoFuncFloor, FloorIntrinsic, DontEnum);
107
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "fround"), 1, mathProtoFuncFround, FRoundIntrinsic, DontEnum);
107
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "fround"), 1, mathProtoFuncFround, FRoundIntrinsic, DontEnum);
108
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "hypot"), 2, mathProtoFuncHypot, NoIntrinsic, DontEnum);
108
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "hypot"), 2, mathProtoFuncHypot, NoIntrinsic, DontEnum);
109
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log"), 1, mathProtoFuncLog, LogIntrinsic, DontEnum);
109
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log"), 1, mathProtoFuncLog, LogIntrinsic, DontEnum);
110
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log10"), 1, mathProtoFuncLog10, NoIntrinsic, DontEnum);
110
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log10"), 1, mathProtoFuncLog10, Log10Intrinsic, DontEnum);
111
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log1p"), 1, mathProtoFuncLog1p, NoIntrinsic, DontEnum);
111
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log1p"), 1, mathProtoFuncLog1p, Log1pIntrinsic, DontEnum);
112
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log2"), 1, mathProtoFuncLog2, NoIntrinsic, DontEnum);
112
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "log2"), 1, mathProtoFuncLog2, Log2Intrinsic, DontEnum);
113
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "max"), 2, mathProtoFuncMax, MaxIntrinsic, DontEnum);
113
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "max"), 2, mathProtoFuncMax, MaxIntrinsic, DontEnum);
114
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "min"), 2, mathProtoFuncMin, MinIntrinsic, DontEnum);
114
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "min"), 2, mathProtoFuncMin, MinIntrinsic, DontEnum);
115
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "pow"), 2, mathProtoFuncPow, PowIntrinsic, DontEnum);
115
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "pow"), 2, mathProtoFuncPow, PowIntrinsic, DontEnum);
Lines 117-126 void MathObject::finishCreation(VM& vm, JSGlobalObject* globalObject) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec3
117
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "round"), 1, mathProtoFuncRound, RoundIntrinsic, DontEnum);
117
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "round"), 1, mathProtoFuncRound, RoundIntrinsic, DontEnum);
118
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sign"), 1, mathProtoFuncSign, NoIntrinsic, DontEnum);
118
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sign"), 1, mathProtoFuncSign, NoIntrinsic, DontEnum);
119
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sin"), 1, mathProtoFuncSin, SinIntrinsic, DontEnum);
119
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sin"), 1, mathProtoFuncSin, SinIntrinsic, DontEnum);
120
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sinh"), 1, mathProtoFuncSinh, NoIntrinsic, DontEnum);
120
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sinh"), 1, mathProtoFuncSinh, SinhIntrinsic, DontEnum);
121
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sqrt"), 1, mathProtoFuncSqrt, SqrtIntrinsic, DontEnum);
121
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "sqrt"), 1, mathProtoFuncSqrt, SqrtIntrinsic, DontEnum);
122
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "tan"), 1, mathProtoFuncTan, TanIntrinsic, DontEnum);
122
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "tan"), 1, mathProtoFuncTan, TanIntrinsic, DontEnum);
123
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "tanh"), 1, mathProtoFuncTanh, NoIntrinsic, DontEnum);
123
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "tanh"), 1, mathProtoFuncTanh, TanhIntrinsic, DontEnum);
124
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "trunc"), 1, mathProtoFuncTrunc, TruncIntrinsic, DontEnum);
124
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "trunc"), 1, mathProtoFuncTrunc, TruncIntrinsic, DontEnum);
125
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "imul"), 2, mathProtoFuncIMul, IMulIntrinsic, DontEnum);
125
    putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier::fromString(&vm, "imul"), 2, mathProtoFuncIMul, IMulIntrinsic, DontEnum);
126
}
126
}
Lines 134-150 EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState* exec) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec4
134
134
135
EncodedJSValue JSC_HOST_CALL mathProtoFuncACos(ExecState* exec)
135
EncodedJSValue JSC_HOST_CALL mathProtoFuncACos(ExecState* exec)
136
{
136
{
137
    return JSValue::encode(jsDoubleNumber(acos(exec->argument(0).toNumber(exec))));
137
    return JSValue::encode(jsDoubleNumber(Math::acos(exec->argument(0).toNumber(exec))));
138
}
138
}
139
139
140
EncodedJSValue JSC_HOST_CALL mathProtoFuncASin(ExecState* exec)
140
EncodedJSValue JSC_HOST_CALL mathProtoFuncASin(ExecState* exec)
141
{
141
{
142
    return JSValue::encode(jsDoubleNumber(asin(exec->argument(0).toNumber(exec))));
142
    return JSValue::encode(jsDoubleNumber(Math::asin(exec->argument(0).toNumber(exec))));
143
}
143
}
144
144
145
EncodedJSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec)
145
EncodedJSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec)
146
{
146
{
147
    return JSValue::encode(jsDoubleNumber(atan(exec->argument(0).toNumber(exec))));
147
    return JSValue::encode(jsDoubleNumber(Math::atan(exec->argument(0).toNumber(exec))));
148
}
148
}
149
149
150
EncodedJSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec)
150
EncodedJSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec)
Lines 170-181 EncodedJSValue JSC_HOST_CALL mathProtoFuncClz32(ExecState* exec) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec5
170
170
171
EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec)
171
EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec)
172
{
172
{
173
    return JSValue::encode(jsDoubleNumber(cos(exec->argument(0).toNumber(exec))));
173
    return JSValue::encode(jsDoubleNumber(Math::cos(exec->argument(0).toNumber(exec))));
174
}
174
}
175
175
176
EncodedJSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec)
176
EncodedJSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec)
177
{
177
{
178
    return JSValue::encode(jsDoubleNumber(exp(exec->argument(0).toNumber(exec))));
178
    return JSValue::encode(jsDoubleNumber(Math::exp(exec->argument(0).toNumber(exec))));
179
}
179
}
180
180
181
EncodedJSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec)
181
EncodedJSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec)
Lines 215-221 EncodedJSValue JSC_HOST_CALL mathProtoFuncHypot(ExecState* exec) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec6
215
215
216
EncodedJSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec)
216
EncodedJSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec)
217
{
217
{
218
    return JSValue::encode(jsDoubleNumber(log(exec->argument(0).toNumber(exec))));
218
    return JSValue::encode(jsDoubleNumber(Math::log(exec->argument(0).toNumber(exec))));
219
}
219
}
220
220
221
EncodedJSValue JSC_HOST_CALL mathProtoFuncMax(ExecState* exec)
221
EncodedJSValue JSC_HOST_CALL mathProtoFuncMax(ExecState* exec)
Lines 278-284 EncodedJSValue JSC_HOST_CALL mathProtoFuncSign(ExecState* exec) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec7
278
278
279
EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec)
279
EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec)
280
{
280
{
281
    return JSValue::encode(jsDoubleNumber(sin(exec->argument(0).toNumber(exec))));
281
    return JSValue::encode(jsDoubleNumber(Math::sin(exec->argument(0).toNumber(exec))));
282
}
282
}
283
283
284
EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec)
284
EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec)
Lines 288-294 EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec8
288
288
289
EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec)
289
EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec)
290
{
290
{
291
    return JSValue::encode(jsDoubleNumber(tan(exec->argument(0).toNumber(exec))));
291
    return JSValue::encode(jsDoubleNumber(Math::tan(exec->argument(0).toNumber(exec))));
292
}
292
}
293
293
294
EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState* exec)
294
EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState* exec)
Lines 304-335 EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState* exec) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec9
304
304
305
EncodedJSValue JSC_HOST_CALL mathProtoFuncACosh(ExecState* exec)
305
EncodedJSValue JSC_HOST_CALL mathProtoFuncACosh(ExecState* exec)
306
{
306
{
307
    return JSValue::encode(jsDoubleNumber(acosh(exec->argument(0).toNumber(exec))));
307
    return JSValue::encode(jsDoubleNumber(Math::acosh(exec->argument(0).toNumber(exec))));
308
}
308
}
309
309
310
EncodedJSValue JSC_HOST_CALL mathProtoFuncASinh(ExecState* exec)
310
EncodedJSValue JSC_HOST_CALL mathProtoFuncASinh(ExecState* exec)
311
{
311
{
312
    return JSValue::encode(jsDoubleNumber(asinh(exec->argument(0).toNumber(exec))));
312
    return JSValue::encode(jsDoubleNumber(Math::asinh(exec->argument(0).toNumber(exec))));
313
}
313
}
314
314
315
EncodedJSValue JSC_HOST_CALL mathProtoFuncATanh(ExecState* exec)
315
EncodedJSValue JSC_HOST_CALL mathProtoFuncATanh(ExecState* exec)
316
{
316
{
317
    return JSValue::encode(jsDoubleNumber(atanh(exec->argument(0).toNumber(exec))));
317
    return JSValue::encode(jsDoubleNumber(Math::atanh(exec->argument(0).toNumber(exec))));
318
}
318
}
319
319
320
EncodedJSValue JSC_HOST_CALL mathProtoFuncCbrt(ExecState* exec)
320
EncodedJSValue JSC_HOST_CALL mathProtoFuncCbrt(ExecState* exec)
321
{
321
{
322
    return JSValue::encode(jsDoubleNumber(cbrt(exec->argument(0).toNumber(exec))));
322
    return JSValue::encode(jsDoubleNumber(Math::cbrt(exec->argument(0).toNumber(exec))));
323
}
323
}
324
324
325
EncodedJSValue JSC_HOST_CALL mathProtoFuncCosh(ExecState* exec)
325
EncodedJSValue JSC_HOST_CALL mathProtoFuncCosh(ExecState* exec)
326
{
326
{
327
    return JSValue::encode(jsDoubleNumber(cosh(exec->argument(0).toNumber(exec))));
327
    return JSValue::encode(jsDoubleNumber(Math::cosh(exec->argument(0).toNumber(exec))));
328
}
328
}
329
329
330
EncodedJSValue JSC_HOST_CALL mathProtoFuncExpm1(ExecState* exec)
330
EncodedJSValue JSC_HOST_CALL mathProtoFuncExpm1(ExecState* exec)
331
{
331
{
332
    return JSValue::encode(jsDoubleNumber(expm1(exec->argument(0).toNumber(exec))));
332
    return JSValue::encode(jsDoubleNumber(Math::expm1(exec->argument(0).toNumber(exec))));
333
}
333
}
334
334
335
EncodedJSValue JSC_HOST_CALL mathProtoFuncFround(ExecState* exec)
335
EncodedJSValue JSC_HOST_CALL mathProtoFuncFround(ExecState* exec)
Lines 339-368 EncodedJSValue JSC_HOST_CALL mathProtoFuncFround(ExecState* exec) a/Source/JavaScriptCore/runtime/MathObject.cpp_sec10
339
339
340
EncodedJSValue JSC_HOST_CALL mathProtoFuncLog1p(ExecState* exec)
340
EncodedJSValue JSC_HOST_CALL mathProtoFuncLog1p(ExecState* exec)
341
{
341
{
342
    double value = exec->argument(0).toNumber(exec);
342
    return JSValue::encode(jsDoubleNumber(Math::log1p(exec->argument(0).toNumber(exec))));
343
    if (value == 0)
344
        return JSValue::encode(jsDoubleNumber(value));
345
    return JSValue::encode(jsDoubleNumber(log1p(value)));
346
}
343
}
347
344
348
EncodedJSValue JSC_HOST_CALL mathProtoFuncLog10(ExecState* exec)
345
EncodedJSValue JSC_HOST_CALL mathProtoFuncLog10(ExecState* exec)
349
{
346
{
350
    return JSValue::encode(jsDoubleNumber(log10(exec->argument(0).toNumber(exec))));
347
    return JSValue::encode(jsDoubleNumber(Math::log10(exec->argument(0).toNumber(exec))));
351
}
348
}
352
349
353
EncodedJSValue JSC_HOST_CALL mathProtoFuncLog2(ExecState* exec)
350
EncodedJSValue JSC_HOST_CALL mathProtoFuncLog2(ExecState* exec)
354
{
351
{
355
    return JSValue::encode(jsDoubleNumber(log2(exec->argument(0).toNumber(exec))));
352
    return JSValue::encode(jsDoubleNumber(Math::log2(exec->argument(0).toNumber(exec))));
356
}
353
}
357
354
358
EncodedJSValue JSC_HOST_CALL mathProtoFuncSinh(ExecState* exec)
355
EncodedJSValue JSC_HOST_CALL mathProtoFuncSinh(ExecState* exec)
359
{
356
{
360
    return JSValue::encode(jsDoubleNumber(sinh(exec->argument(0).toNumber(exec))));
357
    return JSValue::encode(jsDoubleNumber(Math::sinh(exec->argument(0).toNumber(exec))));
361
}
358
}
362
359
363
EncodedJSValue JSC_HOST_CALL mathProtoFuncTanh(ExecState* exec)
360
EncodedJSValue JSC_HOST_CALL mathProtoFuncTanh(ExecState* exec)
364
{
361
{
365
    return JSValue::encode(jsDoubleNumber(tanh(exec->argument(0).toNumber(exec))));
362
    return JSValue::encode(jsDoubleNumber(Math::tanh(exec->argument(0).toNumber(exec))));
366
}
363
}
367
364
368
EncodedJSValue JSC_HOST_CALL mathProtoFuncTrunc(ExecState*exec)
365
EncodedJSValue JSC_HOST_CALL mathProtoFuncTrunc(ExecState*exec)
- a/JSTests/ChangeLog +270 lines
Lines 1-5 a/JSTests/ChangeLog_sec1
1
2017-04-27  Yusuke Suzuki  <utatane.tea@gmail.com>
1
2017-04-27  Yusuke Suzuki  <utatane.tea@gmail.com>
2
2
3
        [JSC] Math unary functions should be handled by DFG
4
        https://bugs.webkit.org/show_bug.cgi?id=171269
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * stress/arith-acos-on-various-types.js: Added.
9
        (let.validInputTypedTestCases.validInputTestCases.map):
10
        (isIdentical):
11
        (opaqueACosNoArgument):
12
        (testNoArgument):
13
        (opaqueAllTypesACos):
14
        (testAllTypesCall):
15
        (testSingleTypeCall):
16
        (testConstant):
17
        (opaqueACosForSideEffects):
18
        (testSideEffect.let.testObject.valueOf):
19
        (testSideEffect):
20
        (opaqueACosForCSE):
21
        (testCSE.let.testObject.valueOf):
22
        (testCSE):
23
        (opaqueACosForDCE):
24
        (testDCE.let.testObject.valueOf):
25
        (testDCE):
26
        (testException.opaqueACosWithException):
27
        (testException):
28
        * stress/arith-acosh-on-various-types.js: Added.
29
        (let.validInputTypedTestCases.validInputTestCases.map):
30
        (isIdentical):
31
        (opaqueACoshNoArgument):
32
        (testNoArgument):
33
        (opaqueAllTypesACosh):
34
        (testAllTypesCall):
35
        (testSingleTypeCall):
36
        (testConstant):
37
        (opaqueACoshForSideEffects):
38
        (testSideEffect.let.testObject.valueOf):
39
        (testSideEffect):
40
        (opaqueACoshForCSE):
41
        (testCSE.let.testObject.valueOf):
42
        (testCSE):
43
        (opaqueACoshForDCE):
44
        (testDCE.let.testObject.valueOf):
45
        (testDCE):
46
        (testException.opaqueACoshWithException):
47
        (testException):
48
        * stress/arith-asin-on-various-types.js: Added.
49
        (let.validInputTypedTestCases.validInputTestCases.map):
50
        (isIdentical):
51
        (opaqueASinNoArgument):
52
        (testNoArgument):
53
        (opaqueAllTypesASin):
54
        (testAllTypesCall):
55
        (testSingleTypeCall):
56
        (testConstant):
57
        (opaqueASinForSideEffects):
58
        (testSideEffect.let.testObject.valueOf):
59
        (testSideEffect):
60
        (opaqueASinForCSE):
61
        (testCSE.let.testObject.valueOf):
62
        (testCSE):
63
        (opaqueASinForDCE):
64
        (testDCE.let.testObject.valueOf):
65
        (testDCE):
66
        (testException.opaqueASinWithException):
67
        (testException):
68
        * stress/arith-asinh-on-various-types.js: Added.
69
        (let.validInputTypedTestCases.validInputTestCases.map):
70
        (isIdentical):
71
        (opaqueASinhNoArgument):
72
        (testNoArgument):
73
        (opaqueAllTypesASinh):
74
        (testAllTypesCall):
75
        (testSingleTypeCall):
76
        (testConstant):
77
        (opaqueASinhForSideEffects):
78
        (testSideEffect.let.testObject.valueOf):
79
        (testSideEffect):
80
        (opaqueASinhForCSE):
81
        (testCSE.let.testObject.valueOf):
82
        (testCSE):
83
        (opaqueASinhForDCE):
84
        (testDCE.let.testObject.valueOf):
85
        (testDCE):
86
        (testException.opaqueASinhWithException):
87
        (testException):
88
        * stress/arith-atan-on-various-types.js: Added.
89
        (let.validInputTypedTestCases.validInputTestCases.map):
90
        (isIdentical):
91
        (opaqueATanNoArgument):
92
        (testNoArgument):
93
        (opaqueAllTypesATan):
94
        (testAllTypesCall):
95
        (testSingleTypeCall):
96
        (testConstant):
97
        (opaqueATanForSideEffects):
98
        (testSideEffect.let.testObject.valueOf):
99
        (testSideEffect):
100
        (opaqueATanForCSE):
101
        (testCSE.let.testObject.valueOf):
102
        (testCSE):
103
        (opaqueATanForDCE):
104
        (testDCE.let.testObject.valueOf):
105
        (testDCE):
106
        (testException.opaqueATanWithException):
107
        (testException):
108
        * stress/arith-atanh-on-various-types.js: Added.
109
        (let.validInputTypedTestCases.validInputTestCases.map):
110
        (isIdentical):
111
        (opaqueATanhNoArgument):
112
        (testNoArgument):
113
        (opaqueAllTypesATanh):
114
        (testAllTypesCall):
115
        (testSingleTypeCall):
116
        (testConstant):
117
        (opaqueATanhForSideEffects):
118
        (testSideEffect.let.testObject.valueOf):
119
        (testSideEffect):
120
        (opaqueATanhForCSE):
121
        (testCSE.let.testObject.valueOf):
122
        (testCSE):
123
        (opaqueATanhForDCE):
124
        (testDCE.let.testObject.valueOf):
125
        (testDCE):
126
        (testException.opaqueATanhWithException):
127
        (testException):
128
        * stress/arith-cbrt-on-various-types.js: Added.
129
        (let.validInputTypedTestCases.validInputTestCases.map):
130
        (isIdentical):
131
        (opaqueCbrtNoArgument):
132
        (testNoArgument):
133
        (opaqueAllTypesCbrt):
134
        (testAllTypesCall):
135
        (testSingleTypeCall):
136
        (testConstant):
137
        (opaqueCbrtForSideEffects):
138
        (testSideEffect.let.testObject.valueOf):
139
        (testSideEffect):
140
        (opaqueCbrtForCSE):
141
        (testCSE.let.testObject.valueOf):
142
        (testCSE):
143
        (opaqueCbrtForDCE):
144
        (testDCE.let.testObject.valueOf):
145
        (testDCE):
146
        (testException.opaqueCbrtWithException):
147
        (testException):
148
        * stress/arith-cosh-on-various-types.js: Added.
149
        (let.validInputTypedTestCases.validInputTestCases.map):
150
        (isIdentical):
151
        (opaqueCoshNoArgument):
152
        (testNoArgument):
153
        (opaqueAllTypesCosh):
154
        (testAllTypesCall):
155
        (testSingleTypeCall):
156
        (testConstant):
157
        (opaqueCoshForSideEffects):
158
        (testSideEffect.let.testObject.valueOf):
159
        (testSideEffect):
160
        (opaqueCoshForCSE):
161
        (testCSE.let.testObject.valueOf):
162
        (testCSE):
163
        (opaqueCoshForDCE):
164
        (testDCE.let.testObject.valueOf):
165
        (testDCE):
166
        (testException.opaqueCoshWithException):
167
        (testException):
168
        * stress/arith-expm1-on-various-types.js: Added.
169
        (let.validInputTypedTestCases.validInputTestCases.map):
170
        (isIdentical):
171
        (opaqueExpm1NoArgument):
172
        (testNoArgument):
173
        (opaqueAllTypesExpm1):
174
        (testAllTypesCall):
175
        (testSingleTypeCall):
176
        (testConstant):
177
        (opaqueExpm1ForSideEffects):
178
        (testSideEffect.let.testObject.valueOf):
179
        (testSideEffect):
180
        (opaqueExpm1ForCSE):
181
        (testCSE.let.testObject.valueOf):
182
        (testCSE):
183
        (opaqueExpm1ForDCE):
184
        (testDCE.let.testObject.valueOf):
185
        (testDCE):
186
        (testException.opaqueExpm1WithException):
187
        (testException):
188
        * stress/arith-log10-on-various-types.js: Added.
189
        (let.validInputTypedTestCases.validInputTestCases.map):
190
        (isIdentical):
191
        (opaqueLog10NoArgument):
192
        (testNoArgument):
193
        (opaqueAllTypesLog10):
194
        (testAllTypesCall):
195
        (testSingleTypeCall):
196
        (testConstant):
197
        (opaqueLog10ForSideEffects):
198
        (testSideEffect.let.testObject.valueOf):
199
        (testSideEffect):
200
        (opaqueLog10ForCSE):
201
        (testCSE.let.testObject.valueOf):
202
        (testCSE):
203
        (opaqueLog10ForDCE):
204
        (testDCE.let.testObject.valueOf):
205
        (testDCE):
206
        (testException.opaqueLog10WithException):
207
        (testException):
208
        * stress/arith-log2-on-various-types.js: Added.
209
        (let.validInputTypedTestCases.validInputTestCases.map):
210
        (isIdentical):
211
        (opaqueLog2NoArgument):
212
        (testNoArgument):
213
        (opaqueAllTypesLog2):
214
        (testAllTypesCall):
215
        (testSingleTypeCall):
216
        (testConstant):
217
        (opaqueLog2ForSideEffects):
218
        (testSideEffect.let.testObject.valueOf):
219
        (testSideEffect):
220
        (opaqueLog2ForCSE):
221
        (testCSE.let.testObject.valueOf):
222
        (testCSE):
223
        (opaqueLog2ForDCE):
224
        (testDCE.let.testObject.valueOf):
225
        (testDCE):
226
        (testException.opaqueLog2WithException):
227
        (testException):
228
        * stress/arith-sinh-on-various-types.js: Added.
229
        (let.validInputTypedTestCases.validInputTestCases.map):
230
        (isIdentical):
231
        (opaqueSinhNoArgument):
232
        (testNoArgument):
233
        (opaqueAllTypesSinh):
234
        (testAllTypesCall):
235
        (testSingleTypeCall):
236
        (testConstant):
237
        (opaqueSinhForSideEffects):
238
        (testSideEffect.let.testObject.valueOf):
239
        (testSideEffect):
240
        (opaqueSinhForCSE):
241
        (testCSE.let.testObject.valueOf):
242
        (testCSE):
243
        (opaqueSinhForDCE):
244
        (testDCE.let.testObject.valueOf):
245
        (testDCE):
246
        (testException.opaqueSinhWithException):
247
        (testException):
248
        * stress/arith-tan-on-various-types.js:
249
        (isIdentical):
250
        * stress/arith-tanh-on-various-types.js: Added.
251
        (let.validInputTypedTestCases.validInputTestCases.map):
252
        (isIdentical):
253
        (opaqueTanhNoArgument):
254
        (testNoArgument):
255
        (opaqueAllTypesTanh):
256
        (testAllTypesCall):
257
        (testSingleTypeCall):
258
        (testConstant):
259
        (opaqueTanhForSideEffects):
260
        (testSideEffect.let.testObject.valueOf):
261
        (testSideEffect):
262
        (opaqueTanhForCSE):
263
        (testCSE.let.testObject.valueOf):
264
        (testCSE):
265
        (opaqueTanhForDCE):
266
        (testDCE.let.testObject.valueOf):
267
        (testDCE):
268
        (testException.opaqueTanhWithException):
269
        (testException):
270
271
2017-04-27  Yusuke Suzuki  <utatane.tea@gmail.com>
272
3
        [JSC] Handle PhantomSpread in LoadVarargs as the same to the others
273
        [JSC] Handle PhantomSpread in LoadVarargs as the same to the others
4
        https://bugs.webkit.org/show_bug.cgi?id=171262
274
        https://bugs.webkit.org/show_bug.cgi?id=171262
5
275
- a/JSTests/stress/arith-acos-on-various-types.js +236 lines
Line 0 a/JSTests/stress/arith-acos-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let acosOfHalf = Math.acos(0.5);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "" + Math.acos(0)],
10
    ["1", "0"],
11
    ["0", "" + Math.acos(0)],
12
    ["-0.", "" + Math.acos(0)],
13
    ["0.5", "" + acosOfHalf],
14
    ["Math.PI", "" + Math.acos(Math.PI)],
15
    ["Infinity", "NaN"],
16
    ["-Infinity", "NaN"],
17
    ["NaN", "NaN"],
18
    ["\"WebKit\"", "NaN"],
19
    ["\"0.5\"", "" + acosOfHalf],
20
    ["{ valueOf: () => { return 0.5; } }", "" + acosOfHalf],
21
];
22
23
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
24
25
function isIdentical(result, expected)
26
{
27
    if (expected === expected) {
28
        if (result !== expected)
29
            return false;
30
        if (!expected)
31
            return (1 / expected) === (1 / result);
32
33
        return true;
34
    }
35
    return result !== result;
36
}
37
38
39
// Test Math.acos() without arguments.
40
function opaqueACosNoArgument() {
41
    return Math.acos();
42
}
43
noInline(opaqueACosNoArgument);
44
noOSRExitFuzzing(opaqueACosNoArgument);
45
46
function testNoArgument() {
47
    for (let i = 0; i < 1e4; ++i) {
48
        let output = opaqueACosNoArgument();
49
        if (output === output) {
50
            throw "Failed opaqueACosNoArgument";
51
        }
52
    }
53
    if (numberOfDFGCompiles(opaqueACosNoArgument) > 1)
54
        throw "The call without arguments should never exit.";
55
}
56
testNoArgument();
57
58
59
// Test Math.acos() with a very polymorphic input. All test cases are seen at each iteration.
60
function opaqueAllTypesACos(argument) {
61
    return Math.acos(argument);
62
}
63
noInline(opaqueAllTypesACos);
64
noOSRExitFuzzing(opaqueAllTypesACos);
65
66
function testAllTypesCall() {
67
    for (let i = 0; i < 1e3; ++i) {
68
        for (let testCaseInput of validInputTypedTestCases) {
69
            let output = opaqueAllTypesACos(testCaseInput[0]);
70
            if (!isIdentical(output, testCaseInput[1]))
71
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
72
        }
73
    }
74
    if (numberOfDFGCompiles(opaqueAllTypesACos) > 2)
75
        throw "We should have detected acos() was polymorphic and generated a generic version.";
76
}
77
testAllTypesCall();
78
79
80
// Test Math.acos() on a completely typed input. Every call see only one type.
81
function testSingleTypeCall() {
82
    for (let testCaseInput of validInputTestCases) {
83
        eval(`
84
            function opaqueACos(argument) {
85
                return Math.acos(argument);
86
            }
87
            noInline(opaqueACos);
88
            noOSRExitFuzzing(opaqueACos);
89
90
            for (let i = 0; i < 1e4; ++i) {
91
                if (!isIdentical(opaqueACos(${testCaseInput[0]}), ${testCaseInput[1]})) {
92
                    throw "Failed testSingleTypeCall()";
93
                }
94
            }
95
            if (numberOfDFGCompiles(opaqueACos) > 1)
96
                throw "We should have compiled a single acos for the expected type.";
97
        `);
98
    }
99
}
100
testSingleTypeCall();
101
102
103
// Test Math.acos() on constants
104
function testConstant() {
105
    for (let testCaseInput of validInputTestCases) {
106
        eval(`
107
            function opaqueACosOnConstant() {
108
                return Math.acos(${testCaseInput[0]});
109
            }
110
            noInline(opaqueACosOnConstant);
111
            noOSRExitFuzzing(opaqueACosOnConstant);
112
113
            for (let i = 0; i < 1e4; ++i) {
114
                if (!isIdentical(opaqueACosOnConstant(), ${testCaseInput[1]})) {
115
                    throw "Failed testConstant()";
116
                }
117
            }
118
            if (numberOfDFGCompiles(opaqueACosOnConstant) > 1)
119
                throw "We should have compiled a single acos for the expected type.";
120
        `);
121
    }
122
}
123
testConstant();
124
125
126
// Verify we call valueOf() exactly once per call.
127
function opaqueACosForSideEffects(argument) {
128
    return Math.acos(argument);
129
}
130
noInline(opaqueACosForSideEffects);
131
noOSRExitFuzzing(opaqueACosForSideEffects);
132
133
function testSideEffect() {
134
    let testObject = {
135
        counter: 0,
136
        valueOf: function() { ++this.counter; return 0.2; }
137
    };
138
    let acosResult = Math.acos(0.2);
139
    for (let i = 0; i < 1e4; ++i) {
140
        if (opaqueACosForSideEffects(testObject) !== acosResult)
141
            throw "Incorrect result in testSideEffect()";
142
    }
143
    if (testObject.counter !== 1e4)
144
        throw "Failed testSideEffect()";
145
    if (numberOfDFGCompiles(opaqueACosForSideEffects) > 1)
146
        throw "opaqueACosForSideEffects() is predictable, it should only be compiled once.";
147
}
148
testSideEffect();
149
150
151
// Verify acos() is not subject to CSE if the argument has side effects.
152
function opaqueACosForCSE(argument) {
153
    return Math.acos(argument) + Math.acos(argument) + Math.acos(argument);
154
}
155
noInline(opaqueACosForCSE);
156
noOSRExitFuzzing(opaqueACosForCSE);
157
158
function testCSE() {
159
    let testObject = {
160
        counter: 0,
161
        valueOf: function() { ++this.counter; return 0.2; }
162
    };
163
    let acosResult = Math.acos(0.2);
164
    let threeacosResult = acosResult + acosResult + acosResult;
165
    for (let i = 0; i < 1e4; ++i) {
166
        if (opaqueACosForCSE(testObject) !== threeacosResult)
167
            throw "Incorrect result in testCSE()";
168
    }
169
    if (testObject.counter !== 3e4)
170
        throw "Failed testCSE()";
171
    if (numberOfDFGCompiles(opaqueACosForCSE) > 1)
172
        throw "opaqueACosForCSE() is predictable, it should only be compiled once.";
173
}
174
testCSE();
175
176
177
// Verify acos() is not subject to DCE if the argument has side effects.
178
function opaqueACosForDCE(argument) {
179
    Math.acos(argument);
180
}
181
noInline(opaqueACosForDCE);
182
noOSRExitFuzzing(opaqueACosForDCE);
183
184
function testDCE() {
185
    let testObject = {
186
        counter: 0,
187
        valueOf: function() { ++this.counter; return 0.2; }
188
    };
189
    for (let i = 0; i < 1e4; ++i) {
190
        opaqueACosForDCE(testObject);
191
    }
192
    if (testObject.counter !== 1e4)
193
        throw "Failed testDCE()";
194
    if (numberOfDFGCompiles(opaqueACosForDCE) > 1)
195
        throw "opaqueACosForDCE() is predictable, it should only be compiled once.";
196
}
197
testDCE();
198
199
200
// Test exceptions in the argument.
201
function testException() {
202
    let counter = 0;
203
    function opaqueACosWithException(argument) {
204
        let result = Math.acos(argument);
205
        ++counter;
206
        return result;
207
    }
208
    noInline(opaqueACosWithException);
209
210
    let testObject = { valueOf: () => {  return 0.1; } };
211
    let acosResult = Math.acos(0.1);
212
213
    // Warm up without exception.
214
    for (let i = 0; i < 1e3; ++i) {
215
        if (opaqueACosWithException(testObject) !== acosResult)
216
            throw "Incorrect result in opaqueACosWithException()";
217
    }
218
219
    let testThrowObject = { valueOf: () => { throw testObject; return 0.1; } };
220
221
    for (let i = 0; i < 1e2; ++i) {
222
        try {
223
            if (opaqueACosWithException(testThrowObject) !== 8)
224
                throw "This code should not be reached!!";
225
        } catch (e) {
226
            if (e !== testObject) {
227
                throw "Wrong object thrown from opaqueACosWithException."
228
            }
229
        }
230
    }
231
232
    if (counter !== 1e3) {
233
        throw "Invalid count in testException()";
234
    }
235
}
236
testException();
- a/JSTests/stress/arith-acosh-on-various-types.js +235 lines
Line 0 a/JSTests/stress/arith-acosh-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let acoshOfFour = Math.acosh(4);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "NaN"],
10
    ["0", "NaN"],
11
    ["-0.", "NaN"],
12
    ["4", "" + acoshOfFour],
13
    ["Math.PI", "" + Math.acosh(Math.PI)],
14
    ["Infinity", "Infinity"],
15
    ["-Infinity", "NaN"],
16
    ["NaN", "NaN"],
17
    ["\"WebKit\"", "NaN"],
18
    ["\"4\"", "" + acoshOfFour],
19
    ["{ valueOf: () => { return 4; } }", "" + acoshOfFour],
20
];
21
22
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
23
24
function isIdentical(result, expected)
25
{
26
    if (expected === expected) {
27
        if (result !== expected)
28
            return false;
29
        if (!expected)
30
            return (1 / expected) === (1 / result);
31
32
        return true;
33
    }
34
    return result !== result;
35
}
36
37
38
// Test Math.acosh() without arguments.
39
function opaqueACoshNoArgument() {
40
    return Math.acosh();
41
}
42
noInline(opaqueACoshNoArgument);
43
noOSRExitFuzzing(opaqueACoshNoArgument);
44
45
function testNoArgument() {
46
    for (let i = 0; i < 1e4; ++i) {
47
        let output = opaqueACoshNoArgument();
48
        if (output === output) {
49
            throw "Failed opaqueACoshNoArgument";
50
        }
51
    }
52
    if (numberOfDFGCompiles(opaqueACoshNoArgument) > 1)
53
        throw "The call without arguments should never exit.";
54
}
55
testNoArgument();
56
57
58
// Test Math.acosh() with a very polymorphic input. All test cases are seen at each iteration.
59
function opaqueAllTypesACosh(argument) {
60
    return Math.acosh(argument);
61
}
62
noInline(opaqueAllTypesACosh);
63
noOSRExitFuzzing(opaqueAllTypesACosh);
64
65
function testAllTypesCall() {
66
    for (let i = 0; i < 1e3; ++i) {
67
        for (let testCaseInput of validInputTypedTestCases) {
68
            let output = opaqueAllTypesACosh(testCaseInput[0]);
69
            if (!isIdentical(output, testCaseInput[1]))
70
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
71
        }
72
    }
73
    if (numberOfDFGCompiles(opaqueAllTypesACosh) > 2)
74
        throw "We should have detected acosh() was polymorphic and generated a generic version.";
75
}
76
testAllTypesCall();
77
78
79
// Test Math.acosh() on a completely typed input. Every call see only one type.
80
function testSingleTypeCall() {
81
    for (let testCaseInput of validInputTestCases) {
82
        eval(`
83
            function opaqueACosh(argument) {
84
                return Math.acosh(argument);
85
            }
86
            noInline(opaqueACosh);
87
            noOSRExitFuzzing(opaqueACosh);
88
89
            for (let i = 0; i < 1e4; ++i) {
90
                if (!isIdentical(opaqueACosh(${testCaseInput[0]}), ${testCaseInput[1]})) {
91
                    throw "Failed testSingleTypeCall()";
92
                }
93
            }
94
            if (numberOfDFGCompiles(opaqueACosh) > 1)
95
                throw "We should have compiled a single acosh for the expected type.";
96
        `);
97
    }
98
}
99
testSingleTypeCall();
100
101
102
// Test Math.acosh() on constants
103
function testConstant() {
104
    for (let testCaseInput of validInputTestCases) {
105
        eval(`
106
            function opaqueACoshOnConstant() {
107
                return Math.acosh(${testCaseInput[0]});
108
            }
109
            noInline(opaqueACoshOnConstant);
110
            noOSRExitFuzzing(opaqueACoshOnConstant);
111
112
            for (let i = 0; i < 1e4; ++i) {
113
                if (!isIdentical(opaqueACoshOnConstant(), ${testCaseInput[1]})) {
114
                    throw "Failed testConstant()";
115
                }
116
            }
117
            if (numberOfDFGCompiles(opaqueACoshOnConstant) > 1)
118
                throw "We should have compiled a single acosh for the expected type.";
119
        `);
120
    }
121
}
122
testConstant();
123
124
125
// Verify we call valueOf() exactly once per call.
126
function opaqueACoshForSideEffects(argument) {
127
    return Math.acosh(argument);
128
}
129
noInline(opaqueACoshForSideEffects);
130
noOSRExitFuzzing(opaqueACoshForSideEffects);
131
132
function testSideEffect() {
133
    let testObject = {
134
        counter: 0,
135
        valueOf: function() { ++this.counter; return 16; }
136
    };
137
    let acosh16 = Math.acosh(16);
138
    for (let i = 0; i < 1e4; ++i) {
139
        if (opaqueACoshForSideEffects(testObject) !== acosh16)
140
            throw "Incorrect result in testSideEffect()";
141
    }
142
    if (testObject.counter !== 1e4)
143
        throw "Failed testSideEffect()";
144
    if (numberOfDFGCompiles(opaqueACoshForSideEffects) > 1)
145
        throw "opaqueACoshForSideEffects() is predictable, it should only be compiled once.";
146
}
147
testSideEffect();
148
149
150
// Verify acosh() is not subject to CSE if the argument has side effects.
151
function opaqueACoshForCSE(argument) {
152
    return Math.acosh(argument) + Math.acosh(argument) + Math.acosh(argument);
153
}
154
noInline(opaqueACoshForCSE);
155
noOSRExitFuzzing(opaqueACoshForCSE);
156
157
function testCSE() {
158
    let testObject = {
159
        counter: 0,
160
        valueOf: function() { ++this.counter; return 16; }
161
    };
162
    let acosh16 = Math.acosh(16);
163
    let threeACosh16 = acosh16 + acosh16 + acosh16;
164
    for (let i = 0; i < 1e4; ++i) {
165
        if (opaqueACoshForCSE(testObject) !== threeACosh16)
166
            throw "Incorrect result in testCSE()";
167
    }
168
    if (testObject.counter !== 3e4)
169
        throw "Failed testCSE()";
170
    if (numberOfDFGCompiles(opaqueACoshForCSE) > 1)
171
        throw "opaqueACoshForCSE() is predictable, it should only be compiled once.";
172
}
173
testCSE();
174
175
176
// Verify acosh() is not subject to DCE if the argument has side effects.
177
function opaqueACoshForDCE(argument) {
178
    Math.acosh(argument);
179
}
180
noInline(opaqueACoshForDCE);
181
noOSRExitFuzzing(opaqueACoshForDCE);
182
183
function testDCE() {
184
    let testObject = {
185
        counter: 0,
186
        valueOf: function() { ++this.counter; return 16; }
187
    };
188
    for (let i = 0; i < 1e4; ++i) {
189
        opaqueACoshForDCE(testObject);
190
    }
191
    if (testObject.counter !== 1e4)
192
        throw "Failed testDCE()";
193
    if (numberOfDFGCompiles(opaqueACoshForDCE) > 1)
194
        throw "opaqueACoshForDCE() is predictable, it should only be compiled once.";
195
}
196
testDCE();
197
198
199
// Test exceptions in the argument.
200
function testException() {
201
    let counter = 0;
202
    function opaqueACoshWithException(argument) {
203
        let result = Math.acosh(argument);
204
        ++counter;
205
        return result;
206
    }
207
    noInline(opaqueACoshWithException);
208
209
    let testObject = { valueOf: () => {  return 64; } };
210
    let acosh64 = Math.acosh(64);
211
212
    // Warm up without exception.
213
    for (let i = 0; i < 1e3; ++i) {
214
        if (opaqueACoshWithException(testObject) !== acosh64)
215
            throw "Incorrect result in opaqueACoshWithException()";
216
    }
217
218
    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
219
220
    for (let i = 0; i < 1e2; ++i) {
221
        try {
222
            if (opaqueACoshWithException(testThrowObject) !== 8)
223
                throw "This code should not be reached!!";
224
        } catch (e) {
225
            if (e !== testObject) {
226
                throw "Wrong object thrown from opaqueACoshWithException."
227
            }
228
        }
229
    }
230
231
    if (counter !== 1e3) {
232
        throw "Invalid count in testException()";
233
    }
234
}
235
testException();
- a/JSTests/stress/arith-asin-on-various-types.js +236 lines
Line 0 a/JSTests/stress/arith-asin-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let asinOfHalf = Math.asin(0.5);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "0"],
10
    ["1", "" + Math.asin(1)],
11
    ["0", "0"],
12
    ["-0.", "-0"],
13
    ["0.5", "" + asinOfHalf],
14
    ["Math.PI", "" + Math.asin(Math.PI)],
15
    ["Infinity", "NaN"],
16
    ["-Infinity", "NaN"],
17
    ["NaN", "NaN"],
18
    ["\"WebKit\"", "NaN"],
19
    ["\"0.5\"", "" + asinOfHalf],
20
    ["{ valueOf: () => { return 0.5; } }", "" + asinOfHalf],
21
];
22
23
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
24
25
function isIdentical(result, expected)
26
{
27
    if (expected === expected) {
28
        if (result !== expected)
29
            return false;
30
        if (!expected)
31
            return (1 / expected) === (1 / result);
32
33
        return true;
34
    }
35
    return result !== result;
36
}
37
38
39
// Test Math.asin() without arguments.
40
function opaqueASinNoArgument() {
41
    return Math.asin();
42
}
43
noInline(opaqueASinNoArgument);
44
noOSRExitFuzzing(opaqueASinNoArgument);
45
46
function testNoArgument() {
47
    for (let i = 0; i < 1e4; ++i) {
48
        let output = opaqueASinNoArgument();
49
        if (output === output) {
50
            throw "Failed opaqueASinNoArgument";
51
        }
52
    }
53
    if (numberOfDFGCompiles(opaqueASinNoArgument) > 1)
54
        throw "The call without arguments should never exit.";
55
}
56
testNoArgument();
57
58
59
// Test Math.asin() with a very polymorphic input. All test cases are seen at each iteration.
60
function opaqueAllTypesASin(argument) {
61
    return Math.asin(argument);
62
}
63
noInline(opaqueAllTypesASin);
64
noOSRExitFuzzing(opaqueAllTypesASin);
65
66
function testAllTypesCall() {
67
    for (let i = 0; i < 1e3; ++i) {
68
        for (let testCaseInput of validInputTypedTestCases) {
69
            let output = opaqueAllTypesASin(testCaseInput[0]);
70
            if (!isIdentical(output, testCaseInput[1]))
71
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
72
        }
73
    }
74
    if (numberOfDFGCompiles(opaqueAllTypesASin) > 2)
75
        throw "We should have detected asin() was polymorphic and generated a generic version.";
76
}
77
testAllTypesCall();
78
79
80
// Test Math.asin() on a completely typed input. Every call see only one type.
81
function testSingleTypeCall() {
82
    for (let testCaseInput of validInputTestCases) {
83
        eval(`
84
            function opaqueASin(argument) {
85
                return Math.asin(argument);
86
            }
87
            noInline(opaqueASin);
88
            noOSRExitFuzzing(opaqueASin);
89
90
            for (let i = 0; i < 1e4; ++i) {
91
                if (!isIdentical(opaqueASin(${testCaseInput[0]}), ${testCaseInput[1]})) {
92
                    throw "Failed testSingleTypeCall()";
93
                }
94
            }
95
            if (numberOfDFGCompiles(opaqueASin) > 1)
96
                throw "We should have compiled a single asin for the expected type.";
97
        `);
98
    }
99
}
100
testSingleTypeCall();
101
102
103
// Test Math.asin() on constants
104
function testConstant() {
105
    for (let testCaseInput of validInputTestCases) {
106
        eval(`
107
            function opaqueASinOnConstant() {
108
                return Math.asin(${testCaseInput[0]});
109
            }
110
            noInline(opaqueASinOnConstant);
111
            noOSRExitFuzzing(opaqueASinOnConstant);
112
113
            for (let i = 0; i < 1e4; ++i) {
114
                if (!isIdentical(opaqueASinOnConstant(), ${testCaseInput[1]})) {
115
                    throw "Failed testConstant()";
116
                }
117
            }
118
            if (numberOfDFGCompiles(opaqueASinOnConstant) > 1)
119
                throw "We should have compiled a single asin for the expected type.";
120
        `);
121
    }
122
}
123
testConstant();
124
125
126
// Verify we call valueOf() exactly once per call.
127
function opaqueASinForSideEffects(argument) {
128
    return Math.asin(argument);
129
}
130
noInline(opaqueASinForSideEffects);
131
noOSRExitFuzzing(opaqueASinForSideEffects);
132
133
function testSideEffect() {
134
    let testObject = {
135
        counter: 0,
136
        valueOf: function() { ++this.counter; return 0.2; }
137
    };
138
    let asinResult = Math.asin(0.2);
139
    for (let i = 0; i < 1e4; ++i) {
140
        if (opaqueASinForSideEffects(testObject) !== asinResult)
141
            throw "Incorrect result in testSideEffect()";
142
    }
143
    if (testObject.counter !== 1e4)
144
        throw "Failed testSideEffect()";
145
    if (numberOfDFGCompiles(opaqueASinForSideEffects) > 1)
146
        throw "opaqueASinForSideEffects() is predictable, it should only be compiled once.";
147
}
148
testSideEffect();
149
150
151
// Verify asin() is not subject to CSE if the argument has side effects.
152
function opaqueASinForCSE(argument) {
153
    return Math.asin(argument) + Math.asin(argument) + Math.asin(argument);
154
}
155
noInline(opaqueASinForCSE);
156
noOSRExitFuzzing(opaqueASinForCSE);
157
158
function testCSE() {
159
    let testObject = {
160
        counter: 0,
161
        valueOf: function() { ++this.counter; return 0.2; }
162
    };
163
    let asinResult = Math.asin(0.2);
164
    let threeasinResult = asinResult + asinResult + asinResult;
165
    for (let i = 0; i < 1e4; ++i) {
166
        if (opaqueASinForCSE(testObject) !== threeasinResult)
167
            throw "Incorrect result in testCSE()";
168
    }
169
    if (testObject.counter !== 3e4)
170
        throw "Failed testCSE()";
171
    if (numberOfDFGCompiles(opaqueASinForCSE) > 1)
172
        throw "opaqueASinForCSE() is predictable, it should only be compiled once.";
173
}
174
testCSE();
175
176
177
// Verify asin() is not subject to DCE if the argument has side effects.
178
function opaqueASinForDCE(argument) {
179
    Math.asin(argument);
180
}
181
noInline(opaqueASinForDCE);
182
noOSRExitFuzzing(opaqueASinForDCE);
183
184
function testDCE() {
185
    let testObject = {
186
        counter: 0,
187
        valueOf: function() { ++this.counter; return 0.2; }
188
    };
189
    for (let i = 0; i < 1e4; ++i) {
190
        opaqueASinForDCE(testObject);
191
    }
192
    if (testObject.counter !== 1e4)
193
        throw "Failed testDCE()";
194
    if (numberOfDFGCompiles(opaqueASinForDCE) > 1)
195
        throw "opaqueASinForDCE() is predictable, it should only be compiled once.";
196
}
197
testDCE();
198
199
200
// Test exceptions in the argument.
201
function testException() {
202
    let counter = 0;
203
    function opaqueASinWithException(argument) {
204
        let result = Math.asin(argument);
205
        ++counter;
206
        return result;
207
    }
208
    noInline(opaqueASinWithException);
209
210
    let testObject = { valueOf: () => {  return 0.1; } };
211
    let asinResult = Math.asin(0.1);
212
213
    // Warm up without exception.
214
    for (let i = 0; i < 1e3; ++i) {
215
        if (opaqueASinWithException(testObject) !== asinResult)
216
            throw "Incorrect result in opaqueASinWithException()";
217
    }
218
219
    let testThrowObject = { valueOf: () => { throw testObject; return 0.1; } };
220
221
    for (let i = 0; i < 1e2; ++i) {
222
        try {
223
            if (opaqueASinWithException(testThrowObject) !== 8)
224
                throw "This code should not be reached!!";
225
        } catch (e) {
226
            if (e !== testObject) {
227
                throw "Wrong object thrown from opaqueASinWithException."
228
            }
229
        }
230
    }
231
232
    if (counter !== 1e3) {
233
        throw "Invalid count in testException()";
234
    }
235
}
236
testException();
- a/JSTests/stress/arith-asinh-on-various-types.js +235 lines
Line 0 a/JSTests/stress/arith-asinh-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let asinhOfFour = Math.asinh(4);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "0"],
10
    ["0", "0"],
11
    ["-0.", "-0"],
12
    ["4", "" + asinhOfFour],
13
    ["Math.PI", "" + Math.asinh(Math.PI)],
14
    ["Infinity", "Infinity"],
15
    ["-Infinity", "-Infinity"],
16
    ["NaN", "NaN"],
17
    ["\"WebKit\"", "NaN"],
18
    ["\"4\"", "" + asinhOfFour],
19
    ["{ valueOf: () => { return 4; } }", "" + asinhOfFour],
20
];
21
22
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
23
24
function isIdentical(result, expected)
25
{
26
    if (expected === expected) {
27
        if (result !== expected)
28
            return false;
29
        if (!expected)
30
            return (1 / expected) === (1 / result);
31
32
        return true;
33
    }
34
    return result !== result;
35
}
36
37
38
// Test Math.asinh() without arguments.
39
function opaqueASinhNoArgument() {
40
    return Math.asinh();
41
}
42
noInline(opaqueASinhNoArgument);
43
noOSRExitFuzzing(opaqueASinhNoArgument);
44
45
function testNoArgument() {
46
    for (let i = 0; i < 1e4; ++i) {
47
        let output = opaqueASinhNoArgument();
48
        if (output === output) {
49
            throw "Failed opaqueASinhNoArgument";
50
        }
51
    }
52
    if (numberOfDFGCompiles(opaqueASinhNoArgument) > 1)
53
        throw "The call without arguments should never exit.";
54
}
55
testNoArgument();
56
57
58
// Test Math.asinh() with a very polymorphic input. All test cases are seen at each iteration.
59
function opaqueAllTypesASinh(argument) {
60
    return Math.asinh(argument);
61
}
62
noInline(opaqueAllTypesASinh);
63
noOSRExitFuzzing(opaqueAllTypesASinh);
64
65
function testAllTypesCall() {
66
    for (let i = 0; i < 1e3; ++i) {
67
        for (let testCaseInput of validInputTypedTestCases) {
68
            let output = opaqueAllTypesASinh(testCaseInput[0]);
69
            if (!isIdentical(output, testCaseInput[1]))
70
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
71
        }
72
    }
73
    if (numberOfDFGCompiles(opaqueAllTypesASinh) > 2)
74
        throw "We should have detected asinh() was polymorphic and generated a generic version.";
75
}
76
testAllTypesCall();
77
78
79
// Test Math.asinh() on a completely typed input. Every call see only one type.
80
function testSingleTypeCall() {
81
    for (let testCaseInput of validInputTestCases) {
82
        eval(`
83
            function opaqueASinh(argument) {
84
                return Math.asinh(argument);
85
            }
86
            noInline(opaqueASinh);
87
            noOSRExitFuzzing(opaqueASinh);
88
89
            for (let i = 0; i < 1e4; ++i) {
90
                if (!isIdentical(opaqueASinh(${testCaseInput[0]}), ${testCaseInput[1]})) {
91
                    throw "Failed testSingleTypeCall()";
92
                }
93
            }
94
            if (numberOfDFGCompiles(opaqueASinh) > 1)
95
                throw "We should have compiled a single asinh for the expected type.";
96
        `);
97
    }
98
}
99
testSingleTypeCall();
100
101
102
// Test Math.asinh() on constants
103
function testConstant() {
104
    for (let testCaseInput of validInputTestCases) {
105
        eval(`
106
            function opaqueASinhOnConstant() {
107
                return Math.asinh(${testCaseInput[0]});
108
            }
109
            noInline(opaqueASinhOnConstant);
110
            noOSRExitFuzzing(opaqueASinhOnConstant);
111
112
            for (let i = 0; i < 1e4; ++i) {
113
                if (!isIdentical(opaqueASinhOnConstant(), ${testCaseInput[1]})) {
114
                    throw "Failed testConstant()";
115
                }
116
            }
117
            if (numberOfDFGCompiles(opaqueASinhOnConstant) > 1)
118
                throw "We should have compiled a single asinh for the expected type.";
119
        `);
120
    }
121
}
122
testConstant();
123
124
125
// Verify we call valueOf() exactly once per call.
126
function opaqueASinhForSideEffects(argument) {
127
    return Math.asinh(argument);
128
}
129
noInline(opaqueASinhForSideEffects);
130
noOSRExitFuzzing(opaqueASinhForSideEffects);
131
132
function testSideEffect() {
133
    let testObject = {
134
        counter: 0,
135
        valueOf: function() { ++this.counter; return 16; }
136
    };
137
    let asinh16 = Math.asinh(16);
138
    for (let i = 0; i < 1e4; ++i) {
139
        if (opaqueASinhForSideEffects(testObject) !== asinh16)
140
            throw "Incorrect result in testSideEffect()";
141
    }
142
    if (testObject.counter !== 1e4)
143
        throw "Failed testSideEffect()";
144
    if (numberOfDFGCompiles(opaqueASinhForSideEffects) > 1)
145
        throw "opaqueASinhForSideEffects() is predictable, it should only be compiled once.";
146
}
147
testSideEffect();
148
149
150
// Verify asinh() is not subject to CSE if the argument has side effects.
151
function opaqueASinhForCSE(argument) {
152
    return Math.asinh(argument) + Math.asinh(argument) + Math.asinh(argument);
153
}
154
noInline(opaqueASinhForCSE);
155
noOSRExitFuzzing(opaqueASinhForCSE);
156
157
function testCSE() {
158
    let testObject = {
159
        counter: 0,
160
        valueOf: function() { ++this.counter; return 16; }
161
    };
162
    let asinh16 = Math.asinh(16);
163
    let threeASinh16 = asinh16 + asinh16 + asinh16;
164
    for (let i = 0; i < 1e4; ++i) {
165
        if (opaqueASinhForCSE(testObject) !== threeASinh16)
166
            throw "Incorrect result in testCSE()";
167
    }
168
    if (testObject.counter !== 3e4)
169
        throw "Failed testCSE()";
170
    if (numberOfDFGCompiles(opaqueASinhForCSE) > 1)
171
        throw "opaqueASinhForCSE() is predictable, it should only be compiled once.";
172
}
173
testCSE();
174
175
176
// Verify asinh() is not subject to DCE if the argument has side effects.
177
function opaqueASinhForDCE(argument) {
178
    Math.asinh(argument);
179
}
180
noInline(opaqueASinhForDCE);
181
noOSRExitFuzzing(opaqueASinhForDCE);
182
183
function testDCE() {
184
    let testObject = {
185
        counter: 0,
186
        valueOf: function() { ++this.counter; return 16; }
187
    };
188
    for (let i = 0; i < 1e4; ++i) {
189
        opaqueASinhForDCE(testObject);
190
    }
191
    if (testObject.counter !== 1e4)
192
        throw "Failed testDCE()";
193
    if (numberOfDFGCompiles(opaqueASinhForDCE) > 1)
194
        throw "opaqueASinhForDCE() is predictable, it should only be compiled once.";
195
}
196
testDCE();
197
198
199
// Test exceptions in the argument.
200
function testException() {
201
    let counter = 0;
202
    function opaqueASinhWithException(argument) {
203
        let result = Math.asinh(argument);
204
        ++counter;
205
        return result;
206
    }
207
    noInline(opaqueASinhWithException);
208
209
    let testObject = { valueOf: () => {  return 64; } };
210
    let asinh64 = Math.asinh(64);
211
212
    // Warm up without exception.
213
    for (let i = 0; i < 1e3; ++i) {
214
        if (opaqueASinhWithException(testObject) !== asinh64)
215
            throw "Incorrect result in opaqueASinhWithException()";
216
    }
217
218
    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
219
220
    for (let i = 0; i < 1e2; ++i) {
221
        try {
222
            if (opaqueASinhWithException(testThrowObject) !== 8)
223
                throw "This code should not be reached!!";
224
        } catch (e) {
225
            if (e !== testObject) {
226
                throw "Wrong object thrown from opaqueASinhWithException."
227
            }
228
        }
229
    }
230
231
    if (counter !== 1e3) {
232
        throw "Invalid count in testException()";
233
    }
234
}
235
testException();
- a/JSTests/stress/arith-atan-on-various-types.js +235 lines
Line 0 a/JSTests/stress/arith-atan-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let atanOfFour = Math.atan(4);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "0"],
10
    ["0", "0"],
11
    ["-0.", "-0"],
12
    ["4", "" + atanOfFour],
13
    ["Math.PI", "" + Math.atan(Math.PI)],
14
    ["Infinity", "" + Math.atan(Infinity)],
15
    ["-Infinity", "-" + Math.atan(Infinity)],
16
    ["NaN", "NaN"],
17
    ["\"WebKit\"", "NaN"],
18
    ["\"4\"", "" + atanOfFour],
19
    ["{ valueOf: () => { return 4; } }", "" + atanOfFour],
20
];
21
22
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
23
24
function isIdentical(result, expected)
25
{
26
    if (expected === expected) {
27
        if (result !== expected)
28
            return false;
29
        if (!expected)
30
            return (1 / expected) === (1 / result);
31
32
        return true;
33
    }
34
    return result !== result;
35
}
36
37
38
// Test Math.atan() without arguments.
39
function opaqueATanNoArgument() {
40
    return Math.atan();
41
}
42
noInline(opaqueATanNoArgument);
43
noOSRExitFuzzing(opaqueATanNoArgument);
44
45
function testNoArgument() {
46
    for (let i = 0; i < 1e4; ++i) {
47
        let output = opaqueATanNoArgument();
48
        if (output === output) {
49
            throw "Failed opaqueATanNoArgument";
50
        }
51
    }
52
    if (numberOfDFGCompiles(opaqueATanNoArgument) > 1)
53
        throw "The call without arguments should never exit.";
54
}
55
testNoArgument();
56
57
58
// Test Math.atan() with a very polymorphic input. All test cases are seen at each iteration.
59
function opaqueAllTypesATan(argument) {
60
    return Math.atan(argument);
61
}
62
noInline(opaqueAllTypesATan);
63
noOSRExitFuzzing(opaqueAllTypesATan);
64
65
function testAllTypesCall() {
66
    for (let i = 0; i < 1e3; ++i) {
67
        for (let testCaseInput of validInputTypedTestCases) {
68
            let output = opaqueAllTypesATan(testCaseInput[0]);
69
            if (!isIdentical(output, testCaseInput[1]))
70
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
71
        }
72
    }
73
    if (numberOfDFGCompiles(opaqueAllTypesATan) > 2)
74
        throw "We should have detected atan() was polymorphic and generated a generic version.";
75
}
76
testAllTypesCall();
77
78
79
// Test Math.atan() on a completely typed input. Every call see only one type.
80
function testSingleTypeCall() {
81
    for (let testCaseInput of validInputTestCases) {
82
        eval(`
83
            function opaqueATan(argument) {
84
                return Math.atan(argument);
85
            }
86
            noInline(opaqueATan);
87
            noOSRExitFuzzing(opaqueATan);
88
89
            for (let i = 0; i < 1e4; ++i) {
90
                if (!isIdentical(opaqueATan(${testCaseInput[0]}), ${testCaseInput[1]})) {
91
                    throw "Failed testSingleTypeCall()";
92
                }
93
            }
94
            if (numberOfDFGCompiles(opaqueATan) > 1)
95
                throw "We should have compiled a single atan for the expected type.";
96
        `);
97
    }
98
}
99
testSingleTypeCall();
100
101
102
// Test Math.atan() on constants
103
function testConstant() {
104
    for (let testCaseInput of validInputTestCases) {
105
        eval(`
106
            function opaqueATanOnConstant() {
107
                return Math.atan(${testCaseInput[0]});
108
            }
109
            noInline(opaqueATanOnConstant);
110
            noOSRExitFuzzing(opaqueATanOnConstant);
111
112
            for (let i = 0; i < 1e4; ++i) {
113
                if (!isIdentical(opaqueATanOnConstant(), ${testCaseInput[1]})) {
114
                    throw "Failed testConstant()";
115
                }
116
            }
117
            if (numberOfDFGCompiles(opaqueATanOnConstant) > 1)
118
                throw "We should have compiled a single atan for the expected type.";
119
        `);
120
    }
121
}
122
testConstant();
123
124
125
// Verify we call valueOf() exactly once per call.
126
function opaqueATanForSideEffects(argument) {
127
    return Math.atan(argument);
128
}
129
noInline(opaqueATanForSideEffects);
130
noOSRExitFuzzing(opaqueATanForSideEffects);
131
132
function testSideEffect() {
133
    let testObject = {
134
        counter: 0,
135
        valueOf: function() { ++this.counter; return 16; }
136
    };
137
    let AtanResult = Math.atan(16);
138
    for (let i = 0; i < 1e4; ++i) {
139
        if (opaqueATanForSideEffects(testObject) !== AtanResult)
140
            throw "Incorrect result in testSideEffect()";
141
    }
142
    if (testObject.counter !== 1e4)
143
        throw "Failed testSideEffect()";
144
    if (numberOfDFGCompiles(opaqueATanForSideEffects) > 1)
145
        throw "opaqueATanForSideEffects() is predictable, it should only be compiled once.";
146
}
147
testSideEffect();
148
149
150
// Verify atan() is not subject to CSE if the argument has side effects.
151
function opaqueATanForCSE(argument) {
152
    return Math.atan(argument) + Math.atan(argument) + Math.atan(argument);
153
}
154
noInline(opaqueATanForCSE);
155
noOSRExitFuzzing(opaqueATanForCSE);
156
157
function testCSE() {
158
    let testObject = {
159
        counter: 0,
160
        valueOf: function() { ++this.counter; return 16; }
161
    };
162
    let AtanResult = Math.atan(16);
163
    let threeAtanResult = AtanResult + AtanResult + AtanResult;
164
    for (let i = 0; i < 1e4; ++i) {
165
        if (opaqueATanForCSE(testObject) !== threeAtanResult)
166
            throw "Incorrect result in testCSE()";
167
    }
168
    if (testObject.counter !== 3e4)
169
        throw "Failed testCSE()";
170
    if (numberOfDFGCompiles(opaqueATanForCSE) > 1)
171
        throw "opaqueATanForCSE() is predictable, it should only be compiled once.";
172
}
173
testCSE();
174
175
176
// Verify atan() is not subject to DCE if the argument has side effects.
177
function opaqueATanForDCE(argument) {
178
    Math.atan(argument);
179
}
180
noInline(opaqueATanForDCE);
181
noOSRExitFuzzing(opaqueATanForDCE);
182
183
function testDCE() {
184
    let testObject = {
185
        counter: 0,
186
        valueOf: function() { ++this.counter; return 16; }
187
    };
188
    for (let i = 0; i < 1e4; ++i) {
189
        opaqueATanForDCE(testObject);
190
    }
191
    if (testObject.counter !== 1e4)
192
        throw "Failed testDCE()";
193
    if (numberOfDFGCompiles(opaqueATanForDCE) > 1)
194
        throw "opaqueATanForDCE() is predictable, it should only be compiled once.";
195
}
196
testDCE();
197
198
199
// Test exceptions in the argument.
200
function testException() {
201
    let counter = 0;
202
    function opaqueATanWithException(argument) {
203
        let result = Math.atan(argument);
204
        ++counter;
205
        return result;
206
    }
207
    noInline(opaqueATanWithException);
208
209
    let testObject = { valueOf: () => {  return 64; } };
210
    let atanResult = Math.atan(64);
211
212
    // Warm up without exception.
213
    for (let i = 0; i < 1e3; ++i) {
214
        if (opaqueATanWithException(testObject) !== atanResult)
215
            throw "Incorrect result in opaqueATanWithException()";
216
    }
217
218
    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
219
220
    for (let i = 0; i < 1e2; ++i) {
221
        try {
222
            if (opaqueATanWithException(testThrowObject) !== 8)
223
                throw "This code should not be reached!!";
224
        } catch (e) {
225
            if (e !== testObject) {
226
                throw "Wrong object thrown from opaqueATanWithException."
227
            }
228
        }
229
    }
230
231
    if (counter !== 1e3) {
232
        throw "Invalid count in testException()";
233
    }
234
}
235
testException();
- a/JSTests/stress/arith-atanh-on-various-types.js +236 lines
Line 0 a/JSTests/stress/arith-atanh-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let atanhOfHalf = Math.atanh(0.5);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "0"],
10
    ["1", "Infinity"],
11
    ["0", "0"],
12
    ["-0.", "-0"],
13
    ["0.5", "" + atanhOfHalf],
14
    ["Math.PI", "" + Math.atanh(Math.PI)],
15
    ["Infinity", "NaN"],
16
    ["-Infinity", "NaN"],
17
    ["NaN", "NaN"],
18
    ["\"WebKit\"", "NaN"],
19
    ["\"0.5\"", "" + atanhOfHalf],
20
    ["{ valueOf: () => { return 0.5; } }", "" + atanhOfHalf],
21
];
22
23
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
24
25
function isIdentical(result, expected)
26
{
27
    if (expected === expected) {
28
        if (result !== expected)
29
            return false;
30
        if (!expected)
31
            return (1 / expected) === (1 / result);
32
33
        return true;
34
    }
35
    return result !== result;
36
}
37
38
39
// Test Math.atanh() without arguments.
40
function opaqueATanhNoArgument() {
41
    return Math.atanh();
42
}
43
noInline(opaqueATanhNoArgument);
44
noOSRExitFuzzing(opaqueATanhNoArgument);
45
46
function testNoArgument() {
47
    for (let i = 0; i < 1e4; ++i) {
48
        let output = opaqueATanhNoArgument();
49
        if (output === output) {
50
            throw "Failed opaqueATanhNoArgument";
51
        }
52
    }
53
    if (numberOfDFGCompiles(opaqueATanhNoArgument) > 1)
54
        throw "The call without arguments should never exit.";
55
}
56
testNoArgument();
57
58
59
// Test Math.atanh() with a very polymorphic input. All test cases are seen at each iteration.
60
function opaqueAllTypesATanh(argument) {
61
    return Math.atanh(argument);
62
}
63
noInline(opaqueAllTypesATanh);
64
noOSRExitFuzzing(opaqueAllTypesATanh);
65
66
function testAllTypesCall() {
67
    for (let i = 0; i < 1e3; ++i) {
68
        for (let testCaseInput of validInputTypedTestCases) {
69
            let output = opaqueAllTypesATanh(testCaseInput[0]);
70
            if (!isIdentical(output, testCaseInput[1]))
71
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
72
        }
73
    }
74
    if (numberOfDFGCompiles(opaqueAllTypesATanh) > 2)
75
        throw "We should have detected atanh() was polymorphic and generated a generic version.";
76
}
77
testAllTypesCall();
78
79
80
// Test Math.atanh() on a completely typed input. Every call see only one type.
81
function testSingleTypeCall() {
82
    for (let testCaseInput of validInputTestCases) {
83
        eval(`
84
            function opaqueATanh(argument) {
85
                return Math.atanh(argument);
86
            }
87
            noInline(opaqueATanh);
88
            noOSRExitFuzzing(opaqueATanh);
89
90
            for (let i = 0; i < 1e4; ++i) {
91
                if (!isIdentical(opaqueATanh(${testCaseInput[0]}), ${testCaseInput[1]})) {
92
                    throw "Failed testSingleTypeCall()";
93
                }
94
            }
95
            if (numberOfDFGCompiles(opaqueATanh) > 1)
96
                throw "We should have compiled a single atanh for the expected type.";
97
        `);
98
    }
99
}
100
testSingleTypeCall();
101
102
103
// Test Math.atanh() on constants
104
function testConstant() {
105
    for (let testCaseInput of validInputTestCases) {
106
        eval(`
107
            function opaqueATanhOnConstant() {
108
                return Math.atanh(${testCaseInput[0]});
109
            }
110
            noInline(opaqueATanhOnConstant);
111
            noOSRExitFuzzing(opaqueATanhOnConstant);
112
113
            for (let i = 0; i < 1e4; ++i) {
114
                if (!isIdentical(opaqueATanhOnConstant(), ${testCaseInput[1]})) {
115
                    throw "Failed testConstant()";
116
                }
117
            }
118
            if (numberOfDFGCompiles(opaqueATanhOnConstant) > 1)
119
                throw "We should have compiled a single atanh for the expected type.";
120
        `);
121
    }
122
}
123
testConstant();
124
125
126
// Verify we call valueOf() exactly once per call.
127
function opaqueATanhForSideEffects(argument) {
128
    return Math.atanh(argument);
129
}
130
noInline(opaqueATanhForSideEffects);
131
noOSRExitFuzzing(opaqueATanhForSideEffects);
132
133
function testSideEffect() {
134
    let testObject = {
135
        counter: 0,
136
        valueOf: function() { ++this.counter; return 0.2; }
137
    };
138
    let atanhResult = Math.atanh(0.2);
139
    for (let i = 0; i < 1e4; ++i) {
140
        if (opaqueATanhForSideEffects(testObject) !== atanhResult)
141
            throw "Incorrect result in testSideEffect()";
142
    }
143
    if (testObject.counter !== 1e4)
144
        throw "Failed testSideEffect()";
145
    if (numberOfDFGCompiles(opaqueATanhForSideEffects) > 1)
146
        throw "opaqueATanhForSideEffects() is predictable, it should only be compiled once.";
147
}
148
testSideEffect();
149
150
151
// Verify atanh() is not subject to CSE if the argument has side effects.
152
function opaqueATanhForCSE(argument) {
153
    return Math.atanh(argument) + Math.atanh(argument) + Math.atanh(argument);
154
}
155
noInline(opaqueATanhForCSE);
156
noOSRExitFuzzing(opaqueATanhForCSE);
157
158
function testCSE() {
159
    let testObject = {
160
        counter: 0,
161
        valueOf: function() { ++this.counter; return 0.2; }
162
    };
163
    let atanhResult = Math.atanh(0.2);
164
    let threeatanhResult = atanhResult + atanhResult + atanhResult;
165
    for (let i = 0; i < 1e4; ++i) {
166
        if (opaqueATanhForCSE(testObject) !== threeatanhResult)
167
            throw "Incorrect result in testCSE()";
168
    }
169
    if (testObject.counter !== 3e4)
170
        throw "Failed testCSE()";
171
    if (numberOfDFGCompiles(opaqueATanhForCSE) > 1)
172
        throw "opaqueATanhForCSE() is predictable, it should only be compiled once.";
173
}
174
testCSE();
175
176
177
// Verify atanh() is not subject to DCE if the argument has side effects.
178
function opaqueATanhForDCE(argument) {
179
    Math.atanh(argument);
180
}
181
noInline(opaqueATanhForDCE);
182
noOSRExitFuzzing(opaqueATanhForDCE);
183
184
function testDCE() {
185
    let testObject = {
186
        counter: 0,
187
        valueOf: function() { ++this.counter; return 0.2; }
188
    };
189
    for (let i = 0; i < 1e4; ++i) {
190
        opaqueATanhForDCE(testObject);
191
    }
192
    if (testObject.counter !== 1e4)
193
        throw "Failed testDCE()";
194
    if (numberOfDFGCompiles(opaqueATanhForDCE) > 1)
195
        throw "opaqueATanhForDCE() is predictable, it should only be compiled once.";
196
}
197
testDCE();
198
199
200
// Test exceptions in the argument.
201
function testException() {
202
    let counter = 0;
203
    function opaqueATanhWithException(argument) {
204
        let result = Math.atanh(argument);
205
        ++counter;
206
        return result;
207
    }
208
    noInline(opaqueATanhWithException);
209
210
    let testObject = { valueOf: () => {  return 0.1; } };
211
    let atanhResult = Math.atanh(0.1);
212
213
    // Warm up without exception.
214
    for (let i = 0; i < 1e3; ++i) {
215
        if (opaqueATanhWithException(testObject) !== atanhResult)
216
            throw "Incorrect result in opaqueATanhWithException()";
217
    }
218
219
    let testThrowObject = { valueOf: () => { throw testObject; return 0.1; } };
220
221
    for (let i = 0; i < 1e2; ++i) {
222
        try {
223
            if (opaqueATanhWithException(testThrowObject) !== 8)
224
                throw "This code should not be reached!!";
225
        } catch (e) {
226
            if (e !== testObject) {
227
                throw "Wrong object thrown from opaqueATanhWithException."
228
            }
229
        }
230
    }
231
232
    if (counter !== 1e3) {
233
        throw "Invalid count in testException()";
234
    }
235
}
236
testException();
- a/JSTests/stress/arith-cbrt-on-various-types.js +237 lines
Line 0 a/JSTests/stress/arith-cbrt-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let cbrtOfHalf = Math.cbrt(0.5);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "0"],
10
    ["1", "1"],
11
    ["0", "0"],
12
    ["-0.", "-0"],
13
    ["-42.", "" + Math.cbrt(-42)],
14
    ["0.5", "" + cbrtOfHalf],
15
    ["Math.PI", "" + Math.cbrt(Math.PI)],
16
    ["Infinity", "Infinity"],
17
    ["-Infinity", "-Infinity"],
18
    ["NaN", "NaN"],
19
    ["\"WebKit\"", "NaN"],
20
    ["\"0.5\"", "" + cbrtOfHalf],
21
    ["{ valueOf: () => { return 0.5; } }", "" + cbrtOfHalf],
22
];
23
24
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
25
26
function isIdentical(result, expected)
27
{
28
    if (expected === expected) {
29
        if (result !== expected)
30
            return false;
31
        if (!expected)
32
            return (1 / expected) === (1 / result);
33
34
        return true;
35
    }
36
    return result !== result;
37
}
38
39
40
// Test Math.cbrt() without arguments.
41
function opaqueCbrtNoArgument() {
42
    return Math.cbrt();
43
}
44
noInline(opaqueCbrtNoArgument);
45
noOSRExitFuzzing(opaqueCbrtNoArgument);
46
47
function testNoArgument() {
48
    for (let i = 0; i < 1e4; ++i) {
49
        let output = opaqueCbrtNoArgument();
50
        if (output === output) {
51
            throw "Failed opaqueCbrtNoArgument";
52
        }
53
    }
54
    if (numberOfDFGCompiles(opaqueCbrtNoArgument) > 1)
55
        throw "The call without arguments should never exit.";
56
}
57
testNoArgument();
58
59
60
// Test Math.cbrt() with a very polymorphic input. All test cases are seen at each iteration.
61
function opaqueAllTypesCbrt(argument) {
62
    return Math.cbrt(argument);
63
}
64
noInline(opaqueAllTypesCbrt);
65
noOSRExitFuzzing(opaqueAllTypesCbrt);
66
67
function testAllTypesCall() {
68
    for (let i = 0; i < 1e3; ++i) {
69
        for (let testCaseInput of validInputTypedTestCases) {
70
            let output = opaqueAllTypesCbrt(testCaseInput[0]);
71
            if (!isIdentical(output, testCaseInput[1]))
72
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
73
        }
74
    }
75
    if (numberOfDFGCompiles(opaqueAllTypesCbrt) > 2)
76
        throw "We should have detected cbrt() was polymorphic and generated a generic version.";
77
}
78
testAllTypesCall();
79
80
81
// Test Math.cbrt() on a completely typed input. Every call see only one type.
82
function testSingleTypeCall() {
83
    for (let testCaseInput of validInputTestCases) {
84
        eval(`
85
            function opaqueCbrt(argument) {
86
                return Math.cbrt(argument);
87
            }
88
            noInline(opaqueCbrt);
89
            noOSRExitFuzzing(opaqueCbrt);
90
91
            for (let i = 0; i < 1e4; ++i) {
92
                if (!isIdentical(opaqueCbrt(${testCaseInput[0]}), ${testCaseInput[1]})) {
93
                    throw "Failed testSingleTypeCall()";
94
                }
95
            }
96
            if (numberOfDFGCompiles(opaqueCbrt) > 1)
97
                throw "We should have compiled a single cbrt for the expected type.";
98
        `);
99
    }
100
}
101
testSingleTypeCall();
102
103
104
// Test Math.cbrt() on constants
105
function testConstant() {
106
    for (let testCaseInput of validInputTestCases) {
107
        eval(`
108
            function opaqueCbrtOnConstant() {
109
                return Math.cbrt(${testCaseInput[0]});
110
            }
111
            noInline(opaqueCbrtOnConstant);
112
            noOSRExitFuzzing(opaqueCbrtOnConstant);
113
114
            for (let i = 0; i < 1e4; ++i) {
115
                if (!isIdentical(opaqueCbrtOnConstant(), ${testCaseInput[1]})) {
116
                    throw "Failed testConstant()";
117
                }
118
            }
119
            if (numberOfDFGCompiles(opaqueCbrtOnConstant) > 1)
120
                throw "We should have compiled a single cbrt for the expected type.";
121
        `);
122
    }
123
}
124
testConstant();
125
126
127
// Verify we call valueOf() exactly once per call.
128
function opaqueCbrtForSideEffects(argument) {
129
    return Math.cbrt(argument);
130
}
131
noInline(opaqueCbrtForSideEffects);
132
noOSRExitFuzzing(opaqueCbrtForSideEffects);
133
134
function testSideEffect() {
135
    let testObject = {
136
        counter: 0,
137
        valueOf: function() { ++this.counter; return 0.2; }
138
    };
139
    let cbrtResult = Math.cbrt(0.2);
140
    for (let i = 0; i < 1e4; ++i) {
141
        if (opaqueCbrtForSideEffects(testObject) !== cbrtResult)
142
            throw "Incorrect result in testSideEffect()";
143
    }
144
    if (testObject.counter !== 1e4)
145
        throw "Failed testSideEffect()";
146
    if (numberOfDFGCompiles(opaqueCbrtForSideEffects) > 1)
147
        throw "opaqueCbrtForSideEffects() is predictable, it should only be compiled once.";
148
}
149
testSideEffect();
150
151
152
// Verify cbrt() is not subject to CSE if the argument has side effects.
153
function opaqueCbrtForCSE(argument) {
154
    return Math.cbrt(argument) + Math.cbrt(argument) + Math.cbrt(argument);
155
}
156
noInline(opaqueCbrtForCSE);
157
noOSRExitFuzzing(opaqueCbrtForCSE);
158
159
function testCSE() {
160
    let testObject = {
161
        counter: 0,
162
        valueOf: function() { ++this.counter; return 0.2; }
163
    };
164
    let cbrtResult = Math.cbrt(0.2);
165
    let threecbrtResult = cbrtResult + cbrtResult + cbrtResult;
166
    for (let i = 0; i < 1e4; ++i) {
167
        if (opaqueCbrtForCSE(testObject) !== threecbrtResult)
168
            throw "Incorrect result in testCSE()";
169
    }
170
    if (testObject.counter !== 3e4)
171
        throw "Failed testCSE()";
172
    if (numberOfDFGCompiles(opaqueCbrtForCSE) > 1)
173
        throw "opaqueCbrtForCSE() is predictable, it should only be compiled once.";
174
}
175
testCSE();
176
177
178
// Verify cbrt() is not subject to DCE if the argument has side effects.
179
function opaqueCbrtForDCE(argument) {
180
    Math.cbrt(argument);
181
}
182
noInline(opaqueCbrtForDCE);
183
noOSRExitFuzzing(opaqueCbrtForDCE);
184
185
function testDCE() {
186
    let testObject = {
187
        counter: 0,
188
        valueOf: function() { ++this.counter; return 0.2; }
189
    };
190
    for (let i = 0; i < 1e4; ++i) {
191
        opaqueCbrtForDCE(testObject);
192
    }
193
    if (testObject.counter !== 1e4)
194
        throw "Failed testDCE()";
195
    if (numberOfDFGCompiles(opaqueCbrtForDCE) > 1)
196
        throw "opaqueCbrtForDCE() is predictable, it should only be compiled once.";
197
}
198
testDCE();
199
200
201
// Test exceptions in the argument.
202
function testException() {
203
    let counter = 0;
204
    function opaqueCbrtWithException(argument) {
205
        let result = Math.cbrt(argument);
206
        ++counter;
207
        return result;
208
    }
209
    noInline(opaqueCbrtWithException);
210
211
    let testObject = { valueOf: () => {  return 0.1; } };
212
    let cbrtResult = Math.cbrt(0.1);
213
214
    // Warm up without exception.
215
    for (let i = 0; i < 1e3; ++i) {
216
        if (opaqueCbrtWithException(testObject) !== cbrtResult)
217
            throw "Incorrect result in opaqueCbrtWithException()";
218
    }
219
220
    let testThrowObject = { valueOf: () => { throw testObject; return 0.1; } };
221
222
    for (let i = 0; i < 1e2; ++i) {
223
        try {
224
            if (opaqueCbrtWithException(testThrowObject) !== 8)
225
                throw "This code should not be reached!!";
226
        } catch (e) {
227
            if (e !== testObject) {
228
                throw "Wrong object thrown from opaqueCbrtWithException."
229
            }
230
        }
231
    }
232
233
    if (counter !== 1e3) {
234
        throw "Invalid count in testException()";
235
    }
236
}
237
testException();
- a/JSTests/stress/arith-cosh-on-various-types.js +235 lines
Line 0 a/JSTests/stress/arith-cosh-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let coshOfFour = Math.cosh(4);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "1"],
10
    ["0", "1"],
11
    ["-0.", "1"],
12
    ["4", "" + coshOfFour],
13
    ["Math.PI", "" + Math.cosh(Math.PI)],
14
    ["Infinity", "Infinity"],
15
    ["-Infinity", "Infinity"],
16
    ["NaN", "NaN"],
17
    ["\"WebKit\"", "NaN"],
18
    ["\"4\"", "" + coshOfFour],
19
    ["{ valueOf: () => { return 4; } }", "" + coshOfFour],
20
];
21
22
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
23
24
function isIdentical(result, expected)
25
{
26
    if (expected === expected) {
27
        if (result !== expected)
28
            return false;
29
        if (!expected)
30
            return (1 / expected) === (1 / result);
31
32
        return true;
33
    }
34
    return result !== result;
35
}
36
37
38
// Test Math.cosh() without arguments.
39
function opaqueCoshNoArgument() {
40
    return Math.cosh();
41
}
42
noInline(opaqueCoshNoArgument);
43
noOSRExitFuzzing(opaqueCoshNoArgument);
44
45
function testNoArgument() {
46
    for (let i = 0; i < 1e4; ++i) {
47
        let output = opaqueCoshNoArgument();
48
        if (output === output) {
49
            throw "Failed opaqueCoshNoArgument";
50
        }
51
    }
52
    if (numberOfDFGCompiles(opaqueCoshNoArgument) > 1)
53
        throw "The call without arguments should never exit.";
54
}
55
testNoArgument();
56
57
58
// Test Math.cosh() with a very polymorphic input. All test cases are seen at each iteration.
59
function opaqueAllTypesCosh(argument) {
60
    return Math.cosh(argument);
61
}
62
noInline(opaqueAllTypesCosh);
63
noOSRExitFuzzing(opaqueAllTypesCosh);
64
65
function testAllTypesCall() {
66
    for (let i = 0; i < 1e3; ++i) {
67
        for (let testCaseInput of validInputTypedTestCases) {
68
            let output = opaqueAllTypesCosh(testCaseInput[0]);
69
            if (!isIdentical(output, testCaseInput[1]))
70
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
71
        }
72
    }
73
    if (numberOfDFGCompiles(opaqueAllTypesCosh) > 2)
74
        throw "We should have detected cosh() was polymorphic and generated a generic version.";
75
}
76
testAllTypesCall();
77
78
79
// Test Math.cosh() on a completely typed input. Every call see only one type.
80
function testSingleTypeCall() {
81
    for (let testCaseInput of validInputTestCases) {
82
        eval(`
83
            function opaqueCosh(argument) {
84
                return Math.cosh(argument);
85
            }
86
            noInline(opaqueCosh);
87
            noOSRExitFuzzing(opaqueCosh);
88
89
            for (let i = 0; i < 1e4; ++i) {
90
                if (!isIdentical(opaqueCosh(${testCaseInput[0]}), ${testCaseInput[1]})) {
91
                    throw "Failed testSingleTypeCall()";
92
                }
93
            }
94
            if (numberOfDFGCompiles(opaqueCosh) > 1)
95
                throw "We should have compiled a single cosh for the expected type.";
96
        `);
97
    }
98
}
99
testSingleTypeCall();
100
101
102
// Test Math.cosh() on constants
103
function testConstant() {
104
    for (let testCaseInput of validInputTestCases) {
105
        eval(`
106
            function opaqueCoshOnConstant() {
107
                return Math.cosh(${testCaseInput[0]});
108
            }
109
            noInline(opaqueCoshOnConstant);
110
            noOSRExitFuzzing(opaqueCoshOnConstant);
111
112
            for (let i = 0; i < 1e4; ++i) {
113
                if (!isIdentical(opaqueCoshOnConstant(), ${testCaseInput[1]})) {
114
                    throw "Failed testConstant()";
115
                }
116
            }
117
            if (numberOfDFGCompiles(opaqueCoshOnConstant) > 1)
118
                throw "We should have compiled a single cosh for the expected type.";
119
        `);
120
    }
121
}
122
testConstant();
123
124
125
// Verify we call valueOf() exactly once per call.
126
function opaqueCoshForSideEffects(argument) {
127
    return Math.cosh(argument);
128
}
129
noInline(opaqueCoshForSideEffects);
130
noOSRExitFuzzing(opaqueCoshForSideEffects);
131
132
function testSideEffect() {
133
    let testObject = {
134
        counter: 0,
135
        valueOf: function() { ++this.counter; return 16; }
136
    };
137
    let cosh16 = Math.cosh(16);
138
    for (let i = 0; i < 1e4; ++i) {
139
        if (opaqueCoshForSideEffects(testObject) !== cosh16)
140
            throw "Incorrect result in testSideEffect()";
141
    }
142
    if (testObject.counter !== 1e4)
143
        throw "Failed testSideEffect()";
144
    if (numberOfDFGCompiles(opaqueCoshForSideEffects) > 1)
145
        throw "opaqueCoshForSideEffects() is predictable, it should only be compiled once.";
146
}
147
testSideEffect();
148
149
150
// Verify cosh() is not subject to CSE if the argument has side effects.
151
function opaqueCoshForCSE(argument) {
152
    return Math.cosh(argument) + Math.cosh(argument) + Math.cosh(argument);
153
}
154
noInline(opaqueCoshForCSE);
155
noOSRExitFuzzing(opaqueCoshForCSE);
156
157
function testCSE() {
158
    let testObject = {
159
        counter: 0,
160
        valueOf: function() { ++this.counter; return 16; }
161
    };
162
    let cosh16 = Math.cosh(16);
163
    let threeCosh16 = cosh16 + cosh16 + cosh16;
164
    for (let i = 0; i < 1e4; ++i) {
165
        if (opaqueCoshForCSE(testObject) !== threeCosh16)
166
            throw "Incorrect result in testCSE()";
167
    }
168
    if (testObject.counter !== 3e4)
169
        throw "Failed testCSE()";
170
    if (numberOfDFGCompiles(opaqueCoshForCSE) > 1)
171
        throw "opaqueCoshForCSE() is predictable, it should only be compiled once.";
172
}
173
testCSE();
174
175
176
// Verify cosh() is not subject to DCE if the argument has side effects.
177
function opaqueCoshForDCE(argument) {
178
    Math.cosh(argument);
179
}
180
noInline(opaqueCoshForDCE);
181
noOSRExitFuzzing(opaqueCoshForDCE);
182
183
function testDCE() {
184
    let testObject = {
185
        counter: 0,
186
        valueOf: function() { ++this.counter; return 16; }
187
    };
188
    for (let i = 0; i < 1e4; ++i) {
189
        opaqueCoshForDCE(testObject);
190
    }
191
    if (testObject.counter !== 1e4)
192
        throw "Failed testDCE()";
193
    if (numberOfDFGCompiles(opaqueCoshForDCE) > 1)
194
        throw "opaqueCoshForDCE() is predictable, it should only be compiled once.";
195
}
196
testDCE();
197
198
199
// Test exceptions in the argument.
200
function testException() {
201
    let counter = 0;
202
    function opaqueCoshWithException(argument) {
203
        let result = Math.cosh(argument);
204
        ++counter;
205
        return result;
206
    }
207
    noInline(opaqueCoshWithException);
208
209
    let testObject = { valueOf: () => {  return 64; } };
210
    let cosh64 = Math.cosh(64);
211
212
    // Warm up without exception.
213
    for (let i = 0; i < 1e3; ++i) {
214
        if (opaqueCoshWithException(testObject) !== cosh64)
215
            throw "Incorrect result in opaqueCoshWithException()";
216
    }
217
218
    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
219
220
    for (let i = 0; i < 1e2; ++i) {
221
        try {
222
            if (opaqueCoshWithException(testThrowObject) !== 8)
223
                throw "This code should not be reached!!";
224
        } catch (e) {
225
            if (e !== testObject) {
226
                throw "Wrong object thrown from opaqueCoshWithException."
227
            }
228
        }
229
    }
230
231
    if (counter !== 1e3) {
232
        throw "Invalid count in testException()";
233
    }
234
}
235
testException();
- a/JSTests/stress/arith-expm1-on-various-types.js +236 lines
Line 0 a/JSTests/stress/arith-expm1-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let expm1OfHalf = Math.expm1(0.5);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "0"],
10
    ["1", "" + Math.expm1(1)],
11
    ["0", "0"],
12
    ["-0.", "-0"],
13
    ["0.5", "" + expm1OfHalf],
14
    ["Math.PI", "" + Math.expm1(Math.PI)],
15
    ["Infinity", "Infinity"],
16
    ["-Infinity", "-1"],
17
    ["NaN", "NaN"],
18
    ["\"WebKit\"", "NaN"],
19
    ["\"0.5\"", "" + expm1OfHalf],
20
    ["{ valueOf: () => { return 0.5; } }", "" + expm1OfHalf],
21
];
22
23
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
24
25
function isIdentical(result, expected)
26
{
27
    if (expected === expected) {
28
        if (result !== expected)
29
            return false;
30
        if (!expected)
31
            return (1 / expected) === (1 / result);
32
33
        return true;
34
    }
35
    return result !== result;
36
}
37
38
39
// Test Math.expm1() without arguments.
40
function opaqueExpm1NoArgument() {
41
    return Math.expm1();
42
}
43
noInline(opaqueExpm1NoArgument);
44
noOSRExitFuzzing(opaqueExpm1NoArgument);
45
46
function testNoArgument() {
47
    for (let i = 0; i < 1e4; ++i) {
48
        let output = opaqueExpm1NoArgument();
49
        if (output === output) {
50
            throw "Failed opaqueExpm1NoArgument";
51
        }
52
    }
53
    if (numberOfDFGCompiles(opaqueExpm1NoArgument) > 1)
54
        throw "The call without arguments should never exit.";
55
}
56
testNoArgument();
57
58
59
// Test Math.expm1() with a very polymorphic input. All test cases are seen at each iteration.
60
function opaqueAllTypesExpm1(argument) {
61
    return Math.expm1(argument);
62
}
63
noInline(opaqueAllTypesExpm1);
64
noOSRExitFuzzing(opaqueAllTypesExpm1);
65
66
function testAllTypesCall() {
67
    for (let i = 0; i < 1e3; ++i) {
68
        for (let testCaseInput of validInputTypedTestCases) {
69
            let output = opaqueAllTypesExpm1(testCaseInput[0]);
70
            if (!isIdentical(output, testCaseInput[1]))
71
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
72
        }
73
    }
74
    if (numberOfDFGCompiles(opaqueAllTypesExpm1) > 2)
75
        throw "We should have detected expm1() was polymorphic and generated a generic version.";
76
}
77
testAllTypesCall();
78
79
80
// Test Math.expm1() on a completely typed input. Every call see only one type.
81
function testSingleTypeCall() {
82
    for (let testCaseInput of validInputTestCases) {
83
        eval(`
84
            function opaqueExpm1(argument) {
85
                return Math.expm1(argument);
86
            }
87
            noInline(opaqueExpm1);
88
            noOSRExitFuzzing(opaqueExpm1);
89
90
            for (let i = 0; i < 1e4; ++i) {
91
                if (!isIdentical(opaqueExpm1(${testCaseInput[0]}), ${testCaseInput[1]})) {
92
                    throw "Failed testSingleTypeCall()";
93
                }
94
            }
95
            if (numberOfDFGCompiles(opaqueExpm1) > 1)
96
                throw "We should have compiled a single expm1 for the expected type.";
97
        `);
98
    }
99
}
100
testSingleTypeCall();
101
102
103
// Test Math.expm1() on constants
104
function testConstant() {
105
    for (let testCaseInput of validInputTestCases) {
106
        eval(`
107
            function opaqueExpm1OnConstant() {
108
                return Math.expm1(${testCaseInput[0]});
109
            }
110
            noInline(opaqueExpm1OnConstant);
111
            noOSRExitFuzzing(opaqueExpm1OnConstant);
112
113
            for (let i = 0; i < 1e4; ++i) {
114
                if (!isIdentical(opaqueExpm1OnConstant(), ${testCaseInput[1]})) {
115
                    throw "Failed testConstant()";
116
                }
117
            }
118
            if (numberOfDFGCompiles(opaqueExpm1OnConstant) > 1)
119
                throw "We should have compiled a single expm1 for the expected type.";
120
        `);
121
    }
122
}
123
testConstant();
124
125
126
// Verify we call valueOf() exactly once per call.
127
function opaqueExpm1ForSideEffects(argument) {
128
    return Math.expm1(argument);
129
}
130
noInline(opaqueExpm1ForSideEffects);
131
noOSRExitFuzzing(opaqueExpm1ForSideEffects);
132
133
function testSideEffect() {
134
    let testObject = {
135
        counter: 0,
136
        valueOf: function() { ++this.counter; return 0.2; }
137
    };
138
    let expm1Result = Math.expm1(0.2);
139
    for (let i = 0; i < 1e4; ++i) {
140
        if (opaqueExpm1ForSideEffects(testObject) !== expm1Result)
141
            throw "Incorrect result in testSideEffect()";
142
    }
143
    if (testObject.counter !== 1e4)
144
        throw "Failed testSideEffect()";
145
    if (numberOfDFGCompiles(opaqueExpm1ForSideEffects) > 1)
146
        throw "opaqueExpm1ForSideEffects() is predictable, it should only be compiled once.";
147
}
148
testSideEffect();
149
150
151
// Verify expm1() is not subject to CSE if the argument has side effects.
152
function opaqueExpm1ForCSE(argument) {
153
    return Math.expm1(argument) + Math.expm1(argument) + Math.expm1(argument);
154
}
155
noInline(opaqueExpm1ForCSE);
156
noOSRExitFuzzing(opaqueExpm1ForCSE);
157
158
function testCSE() {
159
    let testObject = {
160
        counter: 0,
161
        valueOf: function() { ++this.counter; return 0.2; }
162
    };
163
    let expm1Result = Math.expm1(0.2);
164
    let threeexpm1Result = expm1Result + expm1Result + expm1Result;
165
    for (let i = 0; i < 1e4; ++i) {
166
        if (opaqueExpm1ForCSE(testObject) !== threeexpm1Result)
167
            throw "Incorrect result in testCSE()";
168
    }
169
    if (testObject.counter !== 3e4)
170
        throw "Failed testCSE()";
171
    if (numberOfDFGCompiles(opaqueExpm1ForCSE) > 1)
172
        throw "opaqueExpm1ForCSE() is predictable, it should only be compiled once.";
173
}
174
testCSE();
175
176
177
// Verify expm1() is not subject to DCE if the argument has side effects.
178
function opaqueExpm1ForDCE(argument) {
179
    Math.expm1(argument);
180
}
181
noInline(opaqueExpm1ForDCE);
182
noOSRExitFuzzing(opaqueExpm1ForDCE);
183
184
function testDCE() {
185
    let testObject = {
186
        counter: 0,
187
        valueOf: function() { ++this.counter; return 0.2; }
188
    };
189
    for (let i = 0; i < 1e4; ++i) {
190
        opaqueExpm1ForDCE(testObject);
191
    }
192
    if (testObject.counter !== 1e4)
193
        throw "Failed testDCE()";
194
    if (numberOfDFGCompiles(opaqueExpm1ForDCE) > 1)
195
        throw "opaqueExpm1ForDCE() is predictable, it should only be compiled once.";
196
}
197
testDCE();
198
199
200
// Test exceptions in the argument.
201
function testException() {
202
    let counter = 0;
203
    function opaqueExpm1WithException(argument) {
204
        let result = Math.expm1(argument);
205
        ++counter;
206
        return result;
207
    }
208
    noInline(opaqueExpm1WithException);
209
210
    let testObject = { valueOf: () => {  return 0.1; } };
211
    let expm1Result = Math.expm1(0.1);
212
213
    // Warm up without exception.
214
    for (let i = 0; i < 1e3; ++i) {
215
        if (opaqueExpm1WithException(testObject) !== expm1Result)
216
            throw "Incorrect result in opaqueExpm1WithException()";
217
    }
218
219
    let testThrowObject = { valueOf: () => { throw testObject; return 0.1; } };
220
221
    for (let i = 0; i < 1e2; ++i) {
222
        try {
223
            if (opaqueExpm1WithException(testThrowObject) !== 8)
224
                throw "This code should not be reached!!";
225
        } catch (e) {
226
            if (e !== testObject) {
227
                throw "Wrong object thrown from opaqueExpm1WithException."
228
            }
229
        }
230
    }
231
232
    if (counter !== 1e3) {
233
        throw "Invalid count in testException()";
234
    }
235
}
236
testException();
- a/JSTests/stress/arith-log10-on-various-types.js +236 lines
Line 0 a/JSTests/stress/arith-log10-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let log10OfHalf = Math.log10(0.5);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "-Infinity"],
10
    ["1", "0"],
11
    ["0", "-Infinity"],
12
    ["-0.", "-Infinity"],
13
    ["0.5", "" + log10OfHalf],
14
    ["Math.PI", "" + Math.log10(Math.PI)],
15
    ["Infinity", "Infinity"],
16
    ["-Infinity", "NaN"],
17
    ["NaN", "NaN"],
18
    ["\"WebKit\"", "NaN"],
19
    ["\"0.5\"", "" + log10OfHalf],
20
    ["{ valueOf: () => { return 0.5; } }", "" + log10OfHalf],
21
];
22
23
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
24
25
function isIdentical(result, expected)
26
{
27
    if (expected === expected) {
28
        if (result !== expected)
29
            return false;
30
        if (!expected)
31
            return (1 / expected) === (1 / result);
32
33
        return true;
34
    }
35
    return result !== result;
36
}
37
38
39
// Test Math.log10() without arguments.
40
function opaqueLog10NoArgument() {
41
    return Math.log10();
42
}
43
noInline(opaqueLog10NoArgument);
44
noOSRExitFuzzing(opaqueLog10NoArgument);
45
46
function testNoArgument() {
47
    for (let i = 0; i < 1e4; ++i) {
48
        let output = opaqueLog10NoArgument();
49
        if (output === output) {
50
            throw "Failed opaqueLog10NoArgument";
51
        }
52
    }
53
    if (numberOfDFGCompiles(opaqueLog10NoArgument) > 1)
54
        throw "The call without arguments should never exit.";
55
}
56
testNoArgument();
57
58
59
// Test Math.log10() with a very polymorphic input. All test cases are seen at each iteration.
60
function opaqueAllTypesLog10(argument) {
61
    return Math.log10(argument);
62
}
63
noInline(opaqueAllTypesLog10);
64
noOSRExitFuzzing(opaqueAllTypesLog10);
65
66
function testAllTypesCall() {
67
    for (let i = 0; i < 1e3; ++i) {
68
        for (let testCaseInput of validInputTypedTestCases) {
69
            let output = opaqueAllTypesLog10(testCaseInput[0]);
70
            if (!isIdentical(output, testCaseInput[1]))
71
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
72
        }
73
    }
74
    if (numberOfDFGCompiles(opaqueAllTypesLog10) > 2)
75
        throw "We should have detected log10() was polymorphic and generated a generic version.";
76
}
77
testAllTypesCall();
78
79
80
// Test Math.log10() on a completely typed input. Every call see only one type.
81
function testSingleTypeCall() {
82
    for (let testCaseInput of validInputTestCases) {
83
        eval(`
84
            function opaqueLog10(argument) {
85
                return Math.log10(argument);
86
            }
87
            noInline(opaqueLog10);
88
            noOSRExitFuzzing(opaqueLog10);
89
90
            for (let i = 0; i < 1e4; ++i) {
91
                if (!isIdentical(opaqueLog10(${testCaseInput[0]}), ${testCaseInput[1]})) {
92
                    throw "Failed testSingleTypeCall()";
93
                }
94
            }
95
            if (numberOfDFGCompiles(opaqueLog10) > 1)
96
                throw "We should have compiled a single log10 for the expected type.";
97
        `);
98
    }
99
}
100
testSingleTypeCall();
101
102
103
// Test Math.log10() on constants
104
function testConstant() {
105
    for (let testCaseInput of validInputTestCases) {
106
        eval(`
107
            function opaqueLog10OnConstant() {
108
                return Math.log10(${testCaseInput[0]});
109
            }
110
            noInline(opaqueLog10OnConstant);
111
            noOSRExitFuzzing(opaqueLog10OnConstant);
112
113
            for (let i = 0; i < 1e4; ++i) {
114
                if (!isIdentical(opaqueLog10OnConstant(), ${testCaseInput[1]})) {
115
                    throw "Failed testConstant()";
116
                }
117
            }
118
            if (numberOfDFGCompiles(opaqueLog10OnConstant) > 1)
119
                throw "We should have compiled a single log10 for the expected type.";
120
        `);
121
    }
122
}
123
testConstant();
124
125
126
// Verify we call valueOf() exactly once per call.
127
function opaqueLog10ForSideEffects(argument) {
128
    return Math.log10(argument);
129
}
130
noInline(opaqueLog10ForSideEffects);
131
noOSRExitFuzzing(opaqueLog10ForSideEffects);
132
133
function testSideEffect() {
134
    let testObject = {
135
        counter: 0,
136
        valueOf: function() { ++this.counter; return 0.2; }
137
    };
138
    let log10Result = Math.log10(0.2);
139
    for (let i = 0; i < 1e4; ++i) {
140
        if (opaqueLog10ForSideEffects(testObject) !== log10Result)
141
            throw "Incorrect result in testSideEffect()";
142
    }
143
    if (testObject.counter !== 1e4)
144
        throw "Failed testSideEffect()";
145
    if (numberOfDFGCompiles(opaqueLog10ForSideEffects) > 1)
146
        throw "opaqueLog10ForSideEffects() is predictable, it should only be compiled once.";
147
}
148
testSideEffect();
149
150
151
// Verify log10() is not subject to CSE if the argument has side effects.
152
function opaqueLog10ForCSE(argument) {
153
    return Math.log10(argument) + Math.log10(argument) + Math.log10(argument);
154
}
155
noInline(opaqueLog10ForCSE);
156
noOSRExitFuzzing(opaqueLog10ForCSE);
157
158
function testCSE() {
159
    let testObject = {
160
        counter: 0,
161
        valueOf: function() { ++this.counter; return 0.2; }
162
    };
163
    let log10Result = Math.log10(0.2);
164
    let threelog10Result = log10Result + log10Result + log10Result;
165
    for (let i = 0; i < 1e4; ++i) {
166
        if (opaqueLog10ForCSE(testObject) !== threelog10Result)
167
            throw "Incorrect result in testCSE()";
168
    }
169
    if (testObject.counter !== 3e4)
170
        throw "Failed testCSE()";
171
    if (numberOfDFGCompiles(opaqueLog10ForCSE) > 1)
172
        throw "opaqueLog10ForCSE() is predictable, it should only be compiled once.";
173
}
174
testCSE();
175
176
177
// Verify log10() is not subject to DCE if the argument has side effects.
178
function opaqueLog10ForDCE(argument) {
179
    Math.log10(argument);
180
}
181
noInline(opaqueLog10ForDCE);
182
noOSRExitFuzzing(opaqueLog10ForDCE);
183
184
function testDCE() {
185
    let testObject = {
186
        counter: 0,
187
        valueOf: function() { ++this.counter; return 0.2; }
188
    };
189
    for (let i = 0; i < 1e4; ++i) {
190
        opaqueLog10ForDCE(testObject);
191
    }
192
    if (testObject.counter !== 1e4)
193
        throw "Failed testDCE()";
194
    if (numberOfDFGCompiles(opaqueLog10ForDCE) > 1)
195
        throw "opaqueLog10ForDCE() is predictable, it should only be compiled once.";
196
}
197
testDCE();
198
199
200
// Test exceptions in the argument.
201
function testException() {
202
    let counter = 0;
203
    function opaqueLog10WithException(argument) {
204
        let result = Math.log10(argument);
205
        ++counter;
206
        return result;
207
    }
208
    noInline(opaqueLog10WithException);
209
210
    let testObject = { valueOf: () => {  return 0.1; } };
211
    let log10Result = Math.log10(0.1);
212
213
    // Warm up without exception.
214
    for (let i = 0; i < 1e3; ++i) {
215
        if (opaqueLog10WithException(testObject) !== log10Result)
216
            throw "Incorrect result in opaqueLog10WithException()";
217
    }
218
219
    let testThrowObject = { valueOf: () => { throw testObject; return 0.1; } };
220
221
    for (let i = 0; i < 1e2; ++i) {
222
        try {
223
            if (opaqueLog10WithException(testThrowObject) !== 8)
224
                throw "This code should not be reached!!";
225
        } catch (e) {
226
            if (e !== testObject) {
227
                throw "Wrong object thrown from opaqueLog10WithException."
228
            }
229
        }
230
    }
231
232
    if (counter !== 1e3) {
233
        throw "Invalid count in testException()";
234
    }
235
}
236
testException();
- a/JSTests/stress/arith-log2-on-various-types.js +236 lines
Line 0 a/JSTests/stress/arith-log2-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let log2OfHalf = Math.log2(0.5);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "-Infinity"],
10
    ["1", "0"],
11
    ["0", "-Infinity"],
12
    ["-0.", "-Infinity"],
13
    ["0.5", "" + log2OfHalf],
14
    ["Math.PI", "" + Math.log2(Math.PI)],
15
    ["Infinity", "Infinity"],
16
    ["-Infinity", "NaN"],
17
    ["NaN", "NaN"],
18
    ["\"WebKit\"", "NaN"],
19
    ["\"0.5\"", "" + log2OfHalf],
20
    ["{ valueOf: () => { return 0.5; } }", "" + log2OfHalf],
21
];
22
23
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
24
25
function isIdentical(result, expected)
26
{
27
    if (expected === expected) {
28
        if (result !== expected)
29
            return false;
30
        if (!expected)
31
            return (1 / expected) === (1 / result);
32
33
        return true;
34
    }
35
    return result !== result;
36
}
37
38
39
// Test Math.log2() without arguments.
40
function opaqueLog2NoArgument() {
41
    return Math.log2();
42
}
43
noInline(opaqueLog2NoArgument);
44
noOSRExitFuzzing(opaqueLog2NoArgument);
45
46
function testNoArgument() {
47
    for (let i = 0; i < 1e4; ++i) {
48
        let output = opaqueLog2NoArgument();
49
        if (output === output) {
50
            throw "Failed opaqueLog2NoArgument";
51
        }
52
    }
53
    if (numberOfDFGCompiles(opaqueLog2NoArgument) > 1)
54
        throw "The call without arguments should never exit.";
55
}
56
testNoArgument();
57
58
59
// Test Math.log2() with a very polymorphic input. All test cases are seen at each iteration.
60
function opaqueAllTypesLog2(argument) {
61
    return Math.log2(argument);
62
}
63
noInline(opaqueAllTypesLog2);
64
noOSRExitFuzzing(opaqueAllTypesLog2);
65
66
function testAllTypesCall() {
67
    for (let i = 0; i < 1e3; ++i) {
68
        for (let testCaseInput of validInputTypedTestCases) {
69
            let output = opaqueAllTypesLog2(testCaseInput[0]);
70
            if (!isIdentical(output, testCaseInput[1]))
71
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
72
        }
73
    }
74
    if (numberOfDFGCompiles(opaqueAllTypesLog2) > 2)
75
        throw "We should have detected log2() was polymorphic and generated a generic version.";
76
}
77
testAllTypesCall();
78
79
80
// Test Math.log2() on a completely typed input. Every call see only one type.
81
function testSingleTypeCall() {
82
    for (let testCaseInput of validInputTestCases) {
83
        eval(`
84
            function opaqueLog2(argument) {
85
                return Math.log2(argument);
86
            }
87
            noInline(opaqueLog2);
88
            noOSRExitFuzzing(opaqueLog2);
89
90
            for (let i = 0; i < 1e4; ++i) {
91
                if (!isIdentical(opaqueLog2(${testCaseInput[0]}), ${testCaseInput[1]})) {
92
                    throw "Failed testSingleTypeCall()";
93
                }
94
            }
95
            if (numberOfDFGCompiles(opaqueLog2) > 1)
96
                throw "We should have compiled a single log2 for the expected type.";
97
        `);
98
    }
99
}
100
testSingleTypeCall();
101
102
103
// Test Math.log2() on constants
104
function testConstant() {
105
    for (let testCaseInput of validInputTestCases) {
106
        eval(`
107
            function opaqueLog2OnConstant() {
108
                return Math.log2(${testCaseInput[0]});
109
            }
110
            noInline(opaqueLog2OnConstant);
111
            noOSRExitFuzzing(opaqueLog2OnConstant);
112
113
            for (let i = 0; i < 1e4; ++i) {
114
                if (!isIdentical(opaqueLog2OnConstant(), ${testCaseInput[1]})) {
115
                    throw "Failed testConstant()";
116
                }
117
            }
118
            if (numberOfDFGCompiles(opaqueLog2OnConstant) > 1)
119
                throw "We should have compiled a single log2 for the expected type.";
120
        `);
121
    }
122
}
123
testConstant();
124
125
126
// Verify we call valueOf() exactly once per call.
127
function opaqueLog2ForSideEffects(argument) {
128
    return Math.log2(argument);
129
}
130
noInline(opaqueLog2ForSideEffects);
131
noOSRExitFuzzing(opaqueLog2ForSideEffects);
132
133
function testSideEffect() {
134
    let testObject = {
135
        counter: 0,
136
        valueOf: function() { ++this.counter; return 0.2; }
137
    };
138
    let log2Result = Math.log2(0.2);
139
    for (let i = 0; i < 1e4; ++i) {
140
        if (opaqueLog2ForSideEffects(testObject) !== log2Result)
141
            throw "Incorrect result in testSideEffect()";
142
    }
143
    if (testObject.counter !== 1e4)
144
        throw "Failed testSideEffect()";
145
    if (numberOfDFGCompiles(opaqueLog2ForSideEffects) > 1)
146
        throw "opaqueLog2ForSideEffects() is predictable, it should only be compiled once.";
147
}
148
testSideEffect();
149
150
151
// Verify log2() is not subject to CSE if the argument has side effects.
152
function opaqueLog2ForCSE(argument) {
153
    return Math.log2(argument) + Math.log2(argument) + Math.log2(argument);
154
}
155
noInline(opaqueLog2ForCSE);
156
noOSRExitFuzzing(opaqueLog2ForCSE);
157
158
function testCSE() {
159
    let testObject = {
160
        counter: 0,
161
        valueOf: function() { ++this.counter; return 0.2; }
162
    };
163
    let log2Result = Math.log2(0.2);
164
    let threelog2Result = log2Result + log2Result + log2Result;
165
    for (let i = 0; i < 1e4; ++i) {
166
        if (opaqueLog2ForCSE(testObject) !== threelog2Result)
167
            throw "Incorrect result in testCSE()";
168
    }
169
    if (testObject.counter !== 3e4)
170
        throw "Failed testCSE()";
171
    if (numberOfDFGCompiles(opaqueLog2ForCSE) > 1)
172
        throw "opaqueLog2ForCSE() is predictable, it should only be compiled once.";
173
}
174
testCSE();
175
176
177
// Verify log2() is not subject to DCE if the argument has side effects.
178
function opaqueLog2ForDCE(argument) {
179
    Math.log2(argument);
180
}
181
noInline(opaqueLog2ForDCE);
182
noOSRExitFuzzing(opaqueLog2ForDCE);
183
184
function testDCE() {
185
    let testObject = {
186
        counter: 0,
187
        valueOf: function() { ++this.counter; return 0.2; }
188
    };
189
    for (let i = 0; i < 1e4; ++i) {
190
        opaqueLog2ForDCE(testObject);
191
    }
192
    if (testObject.counter !== 1e4)
193
        throw "Failed testDCE()";
194
    if (numberOfDFGCompiles(opaqueLog2ForDCE) > 1)
195
        throw "opaqueLog2ForDCE() is predictable, it should only be compiled once.";
196
}
197
testDCE();
198
199
200
// Test exceptions in the argument.
201
function testException() {
202
    let counter = 0;
203
    function opaqueLog2WithException(argument) {
204
        let result = Math.log2(argument);
205
        ++counter;
206
        return result;
207
    }
208
    noInline(opaqueLog2WithException);
209
210
    let testObject = { valueOf: () => {  return 0.1; } };
211
    let log2Result = Math.log2(0.1);
212
213
    // Warm up without exception.
214
    for (let i = 0; i < 1e3; ++i) {
215
        if (opaqueLog2WithException(testObject) !== log2Result)
216
            throw "Incorrect result in opaqueLog2WithException()";
217
    }
218
219
    let testThrowObject = { valueOf: () => { throw testObject; return 0.1; } };
220
221
    for (let i = 0; i < 1e2; ++i) {
222
        try {
223
            if (opaqueLog2WithException(testThrowObject) !== 8)
224
                throw "This code should not be reached!!";
225
        } catch (e) {
226
            if (e !== testObject) {
227
                throw "Wrong object thrown from opaqueLog2WithException."
228
            }
229
        }
230
    }
231
232
    if (counter !== 1e3) {
233
        throw "Invalid count in testException()";
234
    }
235
}
236
testException();
- a/JSTests/stress/arith-sinh-on-various-types.js +235 lines
Line 0 a/JSTests/stress/arith-sinh-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let sinhOfFour = Math.sinh(4);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "0"],
10
    ["0", "0"],
11
    ["-0.", "-0"],
12
    ["4", "" + sinhOfFour],
13
    ["Math.PI", "" + Math.sinh(Math.PI)],
14
    ["Infinity", "Infinity"],
15
    ["-Infinity", "-Infinity"],
16
    ["NaN", "NaN"],
17
    ["\"WebKit\"", "NaN"],
18
    ["\"4\"", "" + sinhOfFour],
19
    ["{ valueOf: () => { return 4; } }", "" + sinhOfFour],
20
];
21
22
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
23
24
function isIdentical(result, expected)
25
{
26
    if (expected === expected) {
27
        if (result !== expected)
28
            return false;
29
        if (!expected)
30
            return (1 / expected) === (1 / result);
31
32
        return true;
33
    }
34
    return result !== result;
35
}
36
37
38
// Test Math.sinh() without arguments.
39
function opaqueSinhNoArgument() {
40
    return Math.sinh();
41
}
42
noInline(opaqueSinhNoArgument);
43
noOSRExitFuzzing(opaqueSinhNoArgument);
44
45
function testNoArgument() {
46
    for (let i = 0; i < 1e4; ++i) {
47
        let output = opaqueSinhNoArgument();
48
        if (output === output) {
49
            throw "Failed opaqueSinhNoArgument";
50
        }
51
    }
52
    if (numberOfDFGCompiles(opaqueSinhNoArgument) > 1)
53
        throw "The call without arguments should never exit.";
54
}
55
testNoArgument();
56
57
58
// Test Math.sinh() with a very polymorphic input. All test cases are seen at each iteration.
59
function opaqueAllTypesSinh(argument) {
60
    return Math.sinh(argument);
61
}
62
noInline(opaqueAllTypesSinh);
63
noOSRExitFuzzing(opaqueAllTypesSinh);
64
65
function testAllTypesCall() {
66
    for (let i = 0; i < 1e3; ++i) {
67
        for (let testCaseInput of validInputTypedTestCases) {
68
            let output = opaqueAllTypesSinh(testCaseInput[0]);
69
            if (!isIdentical(output, testCaseInput[1]))
70
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
71
        }
72
    }
73
    if (numberOfDFGCompiles(opaqueAllTypesSinh) > 2)
74
        throw "We should have detected sinh() was polymorphic and generated a generic version.";
75
}
76
testAllTypesCall();
77
78
79
// Test Math.sinh() on a completely typed input. Every call see only one type.
80
function testSingleTypeCall() {
81
    for (let testCaseInput of validInputTestCases) {
82
        eval(`
83
            function opaqueSinh(argument) {
84
                return Math.sinh(argument);
85
            }
86
            noInline(opaqueSinh);
87
            noOSRExitFuzzing(opaqueSinh);
88
89
            for (let i = 0; i < 1e4; ++i) {
90
                if (!isIdentical(opaqueSinh(${testCaseInput[0]}), ${testCaseInput[1]})) {
91
                    throw "Failed testSingleTypeCall()";
92
                }
93
            }
94
            if (numberOfDFGCompiles(opaqueSinh) > 1)
95
                throw "We should have compiled a single sinh for the expected type.";
96
        `);
97
    }
98
}
99
testSingleTypeCall();
100
101
102
// Test Math.sinh() on constants
103
function testConstant() {
104
    for (let testCaseInput of validInputTestCases) {
105
        eval(`
106
            function opaqueSinhOnConstant() {
107
                return Math.sinh(${testCaseInput[0]});
108
            }
109
            noInline(opaqueSinhOnConstant);
110
            noOSRExitFuzzing(opaqueSinhOnConstant);
111
112
            for (let i = 0; i < 1e4; ++i) {
113
                if (!isIdentical(opaqueSinhOnConstant(), ${testCaseInput[1]})) {
114
                    throw "Failed testConstant()";
115
                }
116
            }
117
            if (numberOfDFGCompiles(opaqueSinhOnConstant) > 1)
118
                throw "We should have compiled a single sinh for the expected type.";
119
        `);
120
    }
121
}
122
testConstant();
123
124
125
// Verify we call valueOf() exactly once per call.
126
function opaqueSinhForSideEffects(argument) {
127
    return Math.sinh(argument);
128
}
129
noInline(opaqueSinhForSideEffects);
130
noOSRExitFuzzing(opaqueSinhForSideEffects);
131
132
function testSideEffect() {
133
    let testObject = {
134
        counter: 0,
135
        valueOf: function() { ++this.counter; return 16; }
136
    };
137
    let sinh16 = Math.sinh(16);
138
    for (let i = 0; i < 1e4; ++i) {
139
        if (opaqueSinhForSideEffects(testObject) !== sinh16)
140
            throw "Incorrect result in testSideEffect()";
141
    }
142
    if (testObject.counter !== 1e4)
143
        throw "Failed testSideEffect()";
144
    if (numberOfDFGCompiles(opaqueSinhForSideEffects) > 1)
145
        throw "opaqueSinhForSideEffects() is predictable, it should only be compiled once.";
146
}
147
testSideEffect();
148
149
150
// Verify sinh() is not subject to CSE if the argument has side effects.
151
function opaqueSinhForCSE(argument) {
152
    return Math.sinh(argument) + Math.sinh(argument) + Math.sinh(argument);
153
}
154
noInline(opaqueSinhForCSE);
155
noOSRExitFuzzing(opaqueSinhForCSE);
156
157
function testCSE() {
158
    let testObject = {
159
        counter: 0,
160
        valueOf: function() { ++this.counter; return 16; }
161
    };
162
    let sinh16 = Math.sinh(16);
163
    let threeSinh16 = sinh16 + sinh16 + sinh16;
164
    for (let i = 0; i < 1e4; ++i) {
165
        if (opaqueSinhForCSE(testObject) !== threeSinh16)
166
            throw "Incorrect result in testCSE()";
167
    }
168
    if (testObject.counter !== 3e4)
169
        throw "Failed testCSE()";
170
    if (numberOfDFGCompiles(opaqueSinhForCSE) > 1)
171
        throw "opaqueSinhForCSE() is predictable, it should only be compiled once.";
172
}
173
testCSE();
174
175
176
// Verify sinh() is not subject to DCE if the argument has side effects.
177
function opaqueSinhForDCE(argument) {
178
    Math.sinh(argument);
179
}
180
noInline(opaqueSinhForDCE);
181
noOSRExitFuzzing(opaqueSinhForDCE);
182
183
function testDCE() {
184
    let testObject = {
185
        counter: 0,
186
        valueOf: function() { ++this.counter; return 16; }
187
    };
188
    for (let i = 0; i < 1e4; ++i) {
189
        opaqueSinhForDCE(testObject);
190
    }
191
    if (testObject.counter !== 1e4)
192
        throw "Failed testDCE()";
193
    if (numberOfDFGCompiles(opaqueSinhForDCE) > 1)
194
        throw "opaqueSinhForDCE() is predictable, it should only be compiled once.";
195
}
196
testDCE();
197
198
199
// Test exceptions in the argument.
200
function testException() {
201
    let counter = 0;
202
    function opaqueSinhWithException(argument) {
203
        let result = Math.sinh(argument);
204
        ++counter;
205
        return result;
206
    }
207
    noInline(opaqueSinhWithException);
208
209
    let testObject = { valueOf: () => {  return 64; } };
210
    let sinh64 = Math.sinh(64);
211
212
    // Warm up without exception.
213
    for (let i = 0; i < 1e3; ++i) {
214
        if (opaqueSinhWithException(testObject) !== sinh64)
215
            throw "Incorrect result in opaqueSinhWithException()";
216
    }
217
218
    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
219
220
    for (let i = 0; i < 1e2; ++i) {
221
        try {
222
            if (opaqueSinhWithException(testThrowObject) !== 8)
223
                throw "This code should not be reached!!";
224
        } catch (e) {
225
            if (e !== testObject) {
226
                throw "Wrong object thrown from opaqueSinhWithException."
227
            }
228
        }
229
    }
230
231
    if (counter !== 1e3) {
232
        throw "Invalid count in testException()";
233
    }
234
}
235
testException();
- a/JSTests/stress/arith-tan-on-various-types.js -2 / +2 lines
Lines 26-33 function isIdentical(result, expected) a/JSTests/stress/arith-tan-on-various-types.js_sec1
26
    if (expected === expected) {
26
    if (expected === expected) {
27
        if (result !== expected)
27
        if (result !== expected)
28
            return false;
28
            return false;
29
        if (!expected && 1 / expected === -Infinity && 1 / result !== -Infinity)
29
        if (!expected)
30
            return false;
30
            return (1 / expected) === (1 / result);
31
31
32
        return true;
32
        return true;
33
    }
33
    }
- a/JSTests/stress/arith-tanh-on-various-types.js +235 lines
Line 0 a/JSTests/stress/arith-tanh-on-various-types.js_sec1
1
//@ defaultNoEagerRun
2
"use strict";
3
4
let tanhOfFour = Math.tanh(4);
5
6
let validInputTestCases = [
7
    // input as string, expected result as string.
8
    ["undefined", "NaN"],
9
    ["null", "0"],
10
    ["0", "0"],
11
    ["-0.", "-0"],
12
    ["4", "" + tanhOfFour],
13
    ["Math.PI", "" + Math.tanh(Math.PI)],
14
    ["Infinity", "1"],
15
    ["-Infinity", "-1"],
16
    ["NaN", "NaN"],
17
    ["\"WebKit\"", "NaN"],
18
    ["\"4\"", "" + tanhOfFour],
19
    ["{ valueOf: () => { return 4; } }", "" + tanhOfFour],
20
];
21
22
let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
23
24
function isIdentical(result, expected)
25
{
26
    if (expected === expected) {
27
        if (result !== expected)
28
            return false;
29
        if (!expected)
30
            return (1 / expected) === (1 / result);
31
32
        return true;
33
    }
34
    return result !== result;
35
}
36
37
38
// Test Math.tanh() without arguments.
39
function opaqueTanhNoArgument() {
40
    return Math.tanh();
41
}
42
noInline(opaqueTanhNoArgument);
43
noOSRExitFuzzing(opaqueTanhNoArgument);
44
45
function testNoArgument() {
46
    for (let i = 0; i < 1e4; ++i) {
47
        let output = opaqueTanhNoArgument();
48
        if (output === output) {
49
            throw "Failed opaqueTanhNoArgument";
50
        }
51
    }
52
    if (numberOfDFGCompiles(opaqueTanhNoArgument) > 1)
53
        throw "The call without arguments should never exit.";
54
}
55
testNoArgument();
56
57
58
// Test Math.tanh() with a very polymorphic input. All test cases are seen at each iteration.
59
function opaqueAllTypesTanh(argument) {
60
    return Math.tanh(argument);
61
}
62
noInline(opaqueAllTypesTanh);
63
noOSRExitFuzzing(opaqueAllTypesTanh);
64
65
function testAllTypesCall() {
66
    for (let i = 0; i < 1e3; ++i) {
67
        for (let testCaseInput of validInputTypedTestCases) {
68
            let output = opaqueAllTypesTanh(testCaseInput[0]);
69
            if (!isIdentical(output, testCaseInput[1]))
70
                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
71
        }
72
    }
73
    if (numberOfDFGCompiles(opaqueAllTypesTanh) > 2)
74
        throw "We should have detected tanh() was polymorphic and generated a generic version.";
75
}
76
testAllTypesCall();
77
78
79
// Test Math.tanh() on a completely typed input. Every call see only one type.
80
function testSingleTypeCall() {
81
    for (let testCaseInput of validInputTestCases) {
82
        eval(`
83
            function opaqueTanh(argument) {
84
                return Math.tanh(argument);
85
            }
86
            noInline(opaqueTanh);
87
            noOSRExitFuzzing(opaqueTanh);
88
89
            for (let i = 0; i < 1e4; ++i) {
90
                if (!isIdentical(opaqueTanh(${testCaseInput[0]}), ${testCaseInput[1]})) {
91
                    throw "Failed testSingleTypeCall()";
92
                }
93
            }
94
            if (numberOfDFGCompiles(opaqueTanh) > 1)
95
                throw "We should have compiled a single tanh for the expected type.";
96
        `);
97
    }
98
}
99
testSingleTypeCall();
100
101
102
// Test Math.tanh() on constants
103
function testConstant() {
104
    for (let testCaseInput of validInputTestCases) {
105
        eval(`
106
            function opaqueTanhOnConstant() {
107
                return Math.tanh(${testCaseInput[0]});
108
            }
109
            noInline(opaqueTanhOnConstant);
110
            noOSRExitFuzzing(opaqueTanhOnConstant);
111
112
            for (let i = 0; i < 1e4; ++i) {
113
                if (!isIdentical(opaqueTanhOnConstant(), ${testCaseInput[1]})) {
114
                    throw "Failed testConstant()";
115
                }
116
            }
117
            if (numberOfDFGCompiles(opaqueTanhOnConstant) > 1)
118
                throw "We should have compiled a single tanh for the expected type.";
119
        `);
120
    }
121
}
122
testConstant();
123
124
125
// Verify we call valueOf() exactly once per call.
126
function opaqueTanhForSideEffects(argument) {
127
    return Math.tanh(argument);
128
}
129
noInline(opaqueTanhForSideEffects);
130
noOSRExitFuzzing(opaqueTanhForSideEffects);
131
132
function testSideEffect() {
133
    let testObject = {
134
        counter: 0,
135
        valueOf: function() { ++this.counter; return 16; }
136
    };
137
    let tanh16 = Math.tanh(16);
138
    for (let i = 0; i < 1e4; ++i) {
139
        if (opaqueTanhForSideEffects(testObject) !== tanh16)
140
            throw "Incorrect result in testSideEffect()";
141
    }
142
    if (testObject.counter !== 1e4)
143
        throw "Failed testSideEffect()";
144
    if (numberOfDFGCompiles(opaqueTanhForSideEffects) > 1)
145
        throw "opaqueTanhForSideEffects() is predictable, it should only be compiled once.";
146
}
147
testSideEffect();
148
149
150
// Verify tanh() is not subject to CSE if the argument has side effects.
151
function opaqueTanhForCSE(argument) {
152
    return Math.tanh(argument) + Math.tanh(argument) + Math.tanh(argument);
153
}
154
noInline(opaqueTanhForCSE);
155
noOSRExitFuzzing(opaqueTanhForCSE);
156
157
function testCSE() {
158
    let testObject = {
159
        counter: 0,
160
        valueOf: function() { ++this.counter; return 16; }
161
    };
162
    let tanh16 = Math.tanh(16);
163
    let threeTanh16 = tanh16 + tanh16 + tanh16;
164
    for (let i = 0; i < 1e4; ++i) {
165
        if (opaqueTanhForCSE(testObject) !== threeTanh16)
166
            throw "Incorrect result in testCSE()";
167
    }
168
    if (testObject.counter !== 3e4)
169
        throw "Failed testCSE()";
170
    if (numberOfDFGCompiles(opaqueTanhForCSE) > 1)
171
        throw "opaqueTanhForCSE() is predictable, it should only be compiled once.";
172
}
173
testCSE();
174
175
176
// Verify tanh() is not subject to DCE if the argument has side effects.
177
function opaqueTanhForDCE(argument) {
178
    Math.tanh(argument);
179
}
180
noInline(opaqueTanhForDCE);
181
noOSRExitFuzzing(opaqueTanhForDCE);
182
183
function testDCE() {
184
    let testObject = {
185
        counter: 0,
186
        valueOf: function() { ++this.counter; return 16; }
187
    };
188
    for (let i = 0; i < 1e4; ++i) {
189
        opaqueTanhForDCE(testObject);
190
    }
191
    if (testObject.counter !== 1e4)
192
        throw "Failed testDCE()";
193
    if (numberOfDFGCompiles(opaqueTanhForDCE) > 1)
194
        throw "opaqueTanhForDCE() is predictable, it should only be compiled once.";
195
}
196
testDCE();
197
198
199
// Test exceptions in the argument.
200
function testException() {
201
    let counter = 0;
202
    function opaqueTanhWithException(argument) {
203
        let result = Math.tanh(argument);
204
        ++counter;
205
        return result;
206
    }
207
    noInline(opaqueTanhWithException);
208
209
    let testObject = { valueOf: () => {  return 64; } };
210
    let tanh64 = Math.tanh(64);
211
212
    // Warm up without exception.
213
    for (let i = 0; i < 1e3; ++i) {
214
        if (opaqueTanhWithException(testObject) !== tanh64)
215
            throw "Incorrect result in opaqueTanhWithException()";
216
    }
217
218
    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
219
220
    for (let i = 0; i < 1e2; ++i) {
221
        try {
222
            if (opaqueTanhWithException(testThrowObject) !== 8)
223
                throw "This code should not be reached!!";
224
        } catch (e) {
225
            if (e !== testObject) {
226
                throw "Wrong object thrown from opaqueTanhWithException."
227
            }
228
        }
229
    }
230
231
    if (counter !== 1e3) {
232
        throw "Invalid count in testException()";
233
    }
234
}
235
testException();

Return to Bug 171269