LCOV - code coverage report
Current view: top level - test/unittests/compiler - js-call-reducer-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 246 255 96.5 %
Date: 2019-04-17 Functions: 58 82 70.7 %

          Line data    Source code
       1             : // Copyright 2018 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <cctype>
       6             : 
       7             : #include "src/compiler/compilation-dependencies.h"
       8             : #include "src/compiler/js-call-reducer.h"
       9             : #include "src/compiler/js-graph.h"
      10             : #include "src/compiler/simplified-operator.h"
      11             : #include "src/feedback-vector.h"
      12             : #include "src/heap/factory.h"
      13             : #include "src/isolate.h"
      14             : #include "test/unittests/compiler/graph-unittest.h"
      15             : #include "test/unittests/compiler/node-test-utils.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : namespace compiler {
      20             : 
      21             : class JSCallReducerTest : public TypedGraphTest {
      22             :  public:
      23          24 :   JSCallReducerTest()
      24          72 :       : TypedGraphTest(3), javascript_(zone()), deps_(broker(), zone()) {
      25          24 :     broker()->SerializeStandardObjects();
      26          24 :   }
      27          48 :   ~JSCallReducerTest() override = default;
      28             : 
      29             :  protected:
      30          50 :   Reduction Reduce(Node* node) {
      31          50 :     MachineOperatorBuilder machine(zone());
      32          50 :     SimplifiedOperatorBuilder simplified(zone());
      33             :     JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified,
      34          50 :                     &machine);
      35             :     // TODO(titzer): mock the GraphReducer here for better unit testing.
      36         100 :     GraphReducer graph_reducer(zone(), graph());
      37             : 
      38             :     JSCallReducer reducer(&graph_reducer, &jsgraph, broker(),
      39          50 :                           JSCallReducer::kNoFlags, &deps_);
      40         100 :     return reducer.Reduce(node);
      41             :   }
      42             : 
      43         100 :   JSOperatorBuilder* javascript() { return &javascript_; }
      44             : 
      45           2 :   Node* GlobalFunction(const char* name) {
      46             :     Handle<JSFunction> f = Handle<JSFunction>::cast(
      47           4 :         Object::GetProperty(
      48             :             isolate(), isolate()->global_object(),
      49           6 :             isolate()->factory()->NewStringFromAsciiChecked(name))
      50             :             .ToHandleChecked());
      51           2 :     return HeapConstant(f);
      52             :   }
      53             : 
      54          37 :   Node* MathFunction(const std::string& name) {
      55             :     Handle<Object> m =
      56          74 :         JSObject::GetProperty(
      57             :             isolate(), isolate()->global_object(),
      58         111 :             isolate()->factory()->NewStringFromAsciiChecked("Math"))
      59          37 :             .ToHandleChecked();
      60             :     Handle<JSFunction> f = Handle<JSFunction>::cast(
      61          74 :         Object::GetProperty(
      62             :             isolate(), m,
      63          74 :             isolate()->factory()->NewStringFromAsciiChecked(name.c_str()))
      64             :             .ToHandleChecked());
      65          37 :     return HeapConstant(f);
      66             :   }
      67             : 
      68           2 :   Node* StringFunction(const char* name) {
      69             :     Handle<Object> m =
      70           4 :         JSObject::GetProperty(
      71             :             isolate(), isolate()->global_object(),
      72           6 :             isolate()->factory()->NewStringFromAsciiChecked("String"))
      73           2 :             .ToHandleChecked();
      74             :     Handle<JSFunction> f = Handle<JSFunction>::cast(
      75           4 :         Object::GetProperty(
      76           4 :             isolate(), m, isolate()->factory()->NewStringFromAsciiChecked(name))
      77             :             .ToHandleChecked());
      78           2 :     return HeapConstant(f);
      79             :   }
      80             : 
      81           5 :   Node* NumberFunction(const char* name) {
      82             :     Handle<Object> m =
      83          10 :         JSObject::GetProperty(
      84             :             isolate(), isolate()->global_object(),
      85          15 :             isolate()->factory()->NewStringFromAsciiChecked("Number"))
      86           5 :             .ToHandleChecked();
      87             :     Handle<JSFunction> f = Handle<JSFunction>::cast(
      88          10 :         Object::GetProperty(
      89          10 :             isolate(), m, isolate()->factory()->NewStringFromAsciiChecked(name))
      90             :             .ToHandleChecked());
      91           5 :     return HeapConstant(f);
      92             :   }
      93             : 
      94          29 :   std::string op_name_for(const char* fnc) {
      95          29 :     std::string string_fnc(fnc);
      96          29 :     char initial = std::toupper(fnc[0]);
      97          87 :     return std::string("Number") + initial +
      98         116 :            string_fnc.substr(1, std::string::npos);
      99             :   }
     100             : 
     101          43 :   const Operator* Call(int arity) {
     102             :     FeedbackVectorSpec spec(zone());
     103             :     spec.AddCallICSlot();
     104          43 :     Handle<FeedbackMetadata> metadata = FeedbackMetadata::New(isolate(), &spec);
     105             :     Handle<SharedFunctionInfo> shared =
     106             :         isolate()->factory()->NewSharedFunctionInfoForBuiltin(
     107          43 :             isolate()->factory()->empty_string(), Builtins::kIllegal);
     108             :     // Set the raw feedback metadata to circumvent checks that we are not
     109             :     // overwriting existing metadata.
     110          86 :     shared->set_raw_outer_scope_info_or_feedback_metadata(*metadata);
     111             :     Handle<ClosureFeedbackCellArray> closure_feedback_cell_array =
     112          43 :         ClosureFeedbackCellArray::New(isolate(), shared);
     113             :     Handle<FeedbackVector> vector =
     114          43 :         FeedbackVector::New(isolate(), shared, closure_feedback_cell_array);
     115             :     VectorSlotPair feedback(vector, FeedbackSlot(0), UNINITIALIZED);
     116          86 :     return javascript()->Call(arity, CallFrequency(), feedback,
     117             :                               ConvertReceiverMode::kAny,
     118          86 :                               SpeculationMode::kAllowSpeculation);
     119             :   }
     120             : 
     121             :  private:
     122             :   JSOperatorBuilder javascript_;
     123             :   CompilationDependencies deps_;
     124             : };
     125             : 
     126       15444 : TEST_F(JSCallReducerTest, PromiseConstructorNoArgs) {
     127             :   Node* promise =
     128           2 :       HeapConstant(handle(native_context()->promise_function(), isolate()));
     129             :   Node* effect = graph()->start();
     130             :   Node* control = graph()->start();
     131           1 :   Node* context = UndefinedConstant();
     132             :   Node* frame_state = graph()->start();
     133             : 
     134             :   Node* construct =
     135           3 :       graph()->NewNode(javascript()->Construct(2), promise, promise, context,
     136             :                        frame_state, effect, control);
     137             : 
     138           1 :   Reduction r = Reduce(construct);
     139             : 
     140           2 :   ASSERT_FALSE(r.Changed());
     141             : }
     142             : 
     143       15444 : TEST_F(JSCallReducerTest, PromiseConstructorSubclass) {
     144             :   Node* promise =
     145           2 :       HeapConstant(handle(native_context()->promise_function(), isolate()));
     146             :   Node* new_target =
     147           2 :       HeapConstant(handle(native_context()->array_function(), isolate()));
     148             :   Node* effect = graph()->start();
     149             :   Node* control = graph()->start();
     150           1 :   Node* context = UndefinedConstant();
     151             :   Node* frame_state = graph()->start();
     152             : 
     153           1 :   Node* executor = UndefinedConstant();
     154             :   Node* construct =
     155           3 :       graph()->NewNode(javascript()->Construct(3), promise, executor,
     156             :                        new_target, context, frame_state, effect, control);
     157             : 
     158           1 :   Reduction r = Reduce(construct);
     159             : 
     160           2 :   ASSERT_FALSE(r.Changed());
     161             : }
     162             : 
     163       15444 : TEST_F(JSCallReducerTest, PromiseConstructorBasic) {
     164             :   Node* promise =
     165           2 :       HeapConstant(handle(native_context()->promise_function(), isolate()));
     166             :   Node* effect = graph()->start();
     167             :   Node* control = graph()->start();
     168           1 :   Node* context = UndefinedConstant();
     169             :   Node* frame_state = graph()->start();
     170             : 
     171           1 :   Node* executor = UndefinedConstant();
     172             :   Node* construct =
     173           3 :       graph()->NewNode(javascript()->Construct(3), promise, executor, promise,
     174             :                        context, frame_state, effect, control);
     175             : 
     176           1 :   Reduction r = Reduce(construct);
     177             : 
     178           1 :   if (FLAG_experimental_inline_promise_constructor) {
     179           1 :     ASSERT_TRUE(r.Changed());
     180             :   } else {
     181           0 :     ASSERT_FALSE(r.Changed());
     182             :   }
     183             : }
     184             : 
     185             : // Exactly the same as PromiseConstructorBasic which expects a reduction,
     186             : // except that we invalidate the protector cell.
     187       15444 : TEST_F(JSCallReducerTest, PromiseConstructorWithHook) {
     188             :   Node* promise =
     189           2 :       HeapConstant(handle(native_context()->promise_function(), isolate()));
     190             :   Node* effect = graph()->start();
     191             :   Node* control = graph()->start();
     192           1 :   Node* context = UndefinedConstant();
     193             :   Node* frame_state = graph()->start();
     194             : 
     195           1 :   Node* executor = UndefinedConstant();
     196             :   Node* construct =
     197           3 :       graph()->NewNode(javascript()->Construct(3), promise, executor, promise,
     198             :                        context, frame_state, effect, control);
     199             : 
     200           1 :   isolate()->InvalidatePromiseHookProtector();
     201             : 
     202           1 :   Reduction r = Reduce(construct);
     203             : 
     204           2 :   ASSERT_FALSE(r.Changed());
     205             : }
     206             : 
     207             : // -----------------------------------------------------------------------------
     208             : // Math unaries
     209             : 
     210             : namespace {
     211             : 
     212             : const char* kMathUnaries[] = {
     213             :     "abs",  "acos",  "acosh", "asin", "asinh", "atan",  "cbrt",
     214             :     "ceil", "cos",   "cosh",  "exp",  "expm1", "floor", "fround",
     215             :     "log",  "log1p", "log10", "log2", "round", "sign",  "sin",
     216             :     "sinh", "sqrt",  "tan",   "tanh", "trunc"};
     217             : 
     218             : }  // namespace
     219             : 
     220       15444 : TEST_F(JSCallReducerTest, MathUnaryWithNumber) {
     221         105 :   TRACED_FOREACH(const char*, fnc, kMathUnaries) {
     222             :     Node* effect = graph()->start();
     223             :     Node* control = graph()->start();
     224          26 :     Node* context = UndefinedConstant();
     225             :     Node* frame_state = graph()->start();
     226          52 :     Node* jsfunction = MathFunction(fnc);
     227          26 :     Node* p0 = Parameter(Type::Any(), 0);
     228          26 :     Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
     229             :                                   context, frame_state, effect, control);
     230          26 :     Reduction r = Reduce(call);
     231          26 :     ASSERT_TRUE(r.Changed());
     232         104 :     EXPECT_THAT(std::string(IrOpcode::Mnemonic(r.replacement()->opcode())),
     233           0 :                 op_name_for(fnc));
     234             :   }
     235             : }
     236             : 
     237             : // -----------------------------------------------------------------------------
     238             : // Math binaries
     239             : 
     240             : namespace {
     241             : 
     242             : const char* kMathBinaries[] = {"atan2", "pow"};
     243             : 
     244             : }  // namespace
     245             : 
     246       15444 : TEST_F(JSCallReducerTest, MathBinaryWithNumber) {
     247           9 :   TRACED_FOREACH(const char*, fnc, kMathBinaries) {
     248           4 :     Node* jsfunction = MathFunction(fnc);
     249             : 
     250             :     Node* effect = graph()->start();
     251             :     Node* control = graph()->start();
     252           2 :     Node* context = UndefinedConstant();
     253             :     Node* frame_state = graph()->start();
     254           2 :     Node* p0 = Parameter(Type::Any(), 0);
     255           2 :     Node* p1 = Parameter(Type::Any(), 0);
     256           2 :     Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
     257             :                                   p1, context, frame_state, effect, control);
     258           2 :     Reduction r = Reduce(call);
     259             : 
     260           2 :     ASSERT_TRUE(r.Changed());
     261           8 :     EXPECT_THAT(std::string(IrOpcode::Mnemonic(r.replacement()->opcode())),
     262           0 :                 op_name_for(fnc));
     263             :   }
     264             : }
     265             : 
     266             : // -----------------------------------------------------------------------------
     267             : // Math.clz32
     268             : 
     269       15444 : TEST_F(JSCallReducerTest, MathClz32WithUnsigned32) {
     270           2 :   Node* jsfunction = MathFunction("clz32");
     271             :   Node* effect = graph()->start();
     272             :   Node* control = graph()->start();
     273           1 :   Node* context = UndefinedConstant();
     274             :   Node* frame_state = graph()->start();
     275             : 
     276           1 :   Node* p0 = Parameter(Type::Unsigned32(), 0);
     277           1 :   Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
     278             :                                 context, frame_state, effect, control);
     279           1 :   Reduction r = Reduce(call);
     280             : 
     281           1 :   ASSERT_TRUE(r.Changed());
     282           7 :   EXPECT_THAT(r.replacement(),
     283           0 :               IsNumberClz32(IsNumberToUint32(IsSpeculativeToNumber(p0))));
     284             : }
     285             : 
     286       15444 : TEST_F(JSCallReducerTest, MathClz32WithUnsigned32NoArg) {
     287           2 :   Node* jsfunction = MathFunction("clz32");
     288             :   Node* effect = graph()->start();
     289             :   Node* control = graph()->start();
     290           1 :   Node* context = UndefinedConstant();
     291             :   Node* frame_state = graph()->start();
     292             : 
     293           1 :   Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
     294             :                                 context, frame_state, effect, control);
     295           1 :   Reduction r = Reduce(call);
     296             : 
     297           1 :   ASSERT_TRUE(r.Changed());
     298           5 :   EXPECT_THAT(r.replacement(), IsNumberConstant(32));
     299             : }
     300             : 
     301             : // -----------------------------------------------------------------------------
     302             : // Math.imul
     303             : 
     304       15444 : TEST_F(JSCallReducerTest, MathImulWithUnsigned32) {
     305           2 :   Node* jsfunction = MathFunction("imul");
     306             : 
     307             :   Node* effect = graph()->start();
     308             :   Node* control = graph()->start();
     309           1 :   Node* context = UndefinedConstant();
     310             :   Node* frame_state = graph()->start();
     311           1 :   Node* p0 = Parameter(Type::Unsigned32(), 0);
     312           1 :   Node* p1 = Parameter(Type::Unsigned32(), 1);
     313           1 :   Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
     314             :                                 p1, context, frame_state, effect, control);
     315           1 :   Reduction r = Reduce(call);
     316             : 
     317           1 :   ASSERT_TRUE(r.Changed());
     318           4 :   EXPECT_THAT(std::string(IrOpcode::Mnemonic(r.replacement()->opcode())),
     319           0 :               op_name_for("imul"));
     320             : }
     321             : 
     322             : // -----------------------------------------------------------------------------
     323             : // Math.min
     324             : 
     325       15444 : TEST_F(JSCallReducerTest, MathMinWithNoArguments) {
     326           2 :   Node* jsfunction = MathFunction("min");
     327             :   Node* effect = graph()->start();
     328             :   Node* control = graph()->start();
     329           1 :   Node* context = UndefinedConstant();
     330             :   Node* frame_state = graph()->start();
     331           1 :   Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
     332             :                                 context, frame_state, effect, control);
     333           1 :   Reduction r = Reduce(call);
     334             : 
     335           1 :   ASSERT_TRUE(r.Changed());
     336           5 :   EXPECT_THAT(r.replacement(), IsNumberConstant(V8_INFINITY));
     337             : }
     338             : 
     339       15444 : TEST_F(JSCallReducerTest, MathMinWithNumber) {
     340           2 :   Node* jsfunction = MathFunction("min");
     341             :   Node* effect = graph()->start();
     342             :   Node* control = graph()->start();
     343           1 :   Node* context = UndefinedConstant();
     344             :   Node* frame_state = graph()->start();
     345           1 :   Node* p0 = Parameter(Type::Any(), 0);
     346           1 :   Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
     347             :                                 context, frame_state, effect, control);
     348           1 :   Reduction r = Reduce(call);
     349             : 
     350           1 :   ASSERT_TRUE(r.Changed());
     351           5 :   EXPECT_THAT(r.replacement(), IsSpeculativeToNumber(p0));
     352             : }
     353             : 
     354       15444 : TEST_F(JSCallReducerTest, MathMinWithTwoArguments) {
     355           2 :   Node* jsfunction = MathFunction("min");
     356             :   Node* effect = graph()->start();
     357             :   Node* control = graph()->start();
     358           1 :   Node* context = UndefinedConstant();
     359             :   Node* frame_state = graph()->start();
     360           1 :   Node* p0 = Parameter(Type::Any(), 0);
     361           1 :   Node* p1 = Parameter(Type::Any(), 1);
     362           1 :   Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
     363             :                                 p1, context, frame_state, effect, control);
     364           1 :   Reduction r = Reduce(call);
     365             : 
     366           1 :   ASSERT_TRUE(r.Changed());
     367           8 :   EXPECT_THAT(r.replacement(), IsNumberMin(IsSpeculativeToNumber(p0),
     368           0 :                                            IsSpeculativeToNumber(p1)));
     369             : }
     370             : 
     371             : // -----------------------------------------------------------------------------
     372             : // Math.max
     373             : 
     374       15444 : TEST_F(JSCallReducerTest, MathMaxWithNoArguments) {
     375           2 :   Node* jsfunction = MathFunction("max");
     376             : 
     377             :   Node* effect = graph()->start();
     378             :   Node* control = graph()->start();
     379           1 :   Node* context = UndefinedConstant();
     380             :   Node* frame_state = graph()->start();
     381           1 :   Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
     382             :                                 context, frame_state, effect, control);
     383           1 :   Reduction r = Reduce(call);
     384             : 
     385           1 :   ASSERT_TRUE(r.Changed());
     386           5 :   EXPECT_THAT(r.replacement(), IsNumberConstant(-V8_INFINITY));
     387             : }
     388             : 
     389       15444 : TEST_F(JSCallReducerTest, MathMaxWithNumber) {
     390           2 :   Node* jsfunction = MathFunction("max");
     391             :   Node* effect = graph()->start();
     392             :   Node* control = graph()->start();
     393           1 :   Node* context = UndefinedConstant();
     394             :   Node* frame_state = graph()->start();
     395           1 :   Node* p0 = Parameter(Type::Any(), 0);
     396           1 :   Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
     397             :                                 context, frame_state, effect, control);
     398           1 :   Reduction r = Reduce(call);
     399             : 
     400           1 :   ASSERT_TRUE(r.Changed());
     401           5 :   EXPECT_THAT(r.replacement(), IsSpeculativeToNumber(p0));
     402             : }
     403             : 
     404       15444 : TEST_F(JSCallReducerTest, MathMaxWithTwoArguments) {
     405           2 :   Node* jsfunction = MathFunction("max");
     406             : 
     407             :   Node* effect = graph()->start();
     408             :   Node* control = graph()->start();
     409           1 :   Node* context = UndefinedConstant();
     410             :   Node* frame_state = graph()->start();
     411           1 :   Node* p0 = Parameter(Type::Any(), 0);
     412           1 :   Node* p1 = Parameter(Type::Any(), 1);
     413           1 :   Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
     414             :                                 p1, context, frame_state, effect, control);
     415           1 :   Reduction r = Reduce(call);
     416             : 
     417           1 :   ASSERT_TRUE(r.Changed());
     418           8 :   EXPECT_THAT(r.replacement(), IsNumberMax(IsSpeculativeToNumber(p0),
     419           0 :                                            IsSpeculativeToNumber(p1)));
     420             : }
     421             : 
     422             : // -----------------------------------------------------------------------------
     423             : // String.fromCharCode
     424             : 
     425       15444 : TEST_F(JSCallReducerTest, StringFromSingleCharCodeWithNumber) {
     426           1 :   Node* function = StringFunction("fromCharCode");
     427             : 
     428             :   Node* effect = graph()->start();
     429             :   Node* control = graph()->start();
     430           1 :   Node* context = UndefinedConstant();
     431             :   Node* frame_state = graph()->start();
     432           1 :   Node* p0 = Parameter(Type::Any(), 0);
     433           1 :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     434             :                                 context, frame_state, effect, control);
     435           1 :   Reduction r = Reduce(call);
     436             : 
     437           1 :   ASSERT_TRUE(r.Changed());
     438           6 :   EXPECT_THAT(r.replacement(),
     439           0 :               IsStringFromSingleCharCode(IsSpeculativeToNumber(p0)));
     440             : }
     441             : 
     442       15444 : TEST_F(JSCallReducerTest, StringFromSingleCharCodeWithPlainPrimitive) {
     443           1 :   Node* function = StringFunction("fromCharCode");
     444             : 
     445             :   Node* effect = graph()->start();
     446             :   Node* control = graph()->start();
     447           1 :   Node* context = UndefinedConstant();
     448             :   Node* frame_state = graph()->start();
     449           1 :   Node* p0 = Parameter(Type::PlainPrimitive(), 0);
     450           1 :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     451             :                                 context, frame_state, effect, control);
     452           1 :   Reduction r = Reduce(call);
     453             : 
     454           1 :   ASSERT_TRUE(r.Changed());
     455           6 :   EXPECT_THAT(r.replacement(),
     456           0 :               IsStringFromSingleCharCode(IsSpeculativeToNumber(p0)));
     457             : }
     458             : 
     459             : // -----------------------------------------------------------------------------
     460             : // Number.isFinite
     461             : 
     462       15444 : TEST_F(JSCallReducerTest, NumberIsFinite) {
     463           1 :   Node* function = NumberFunction("isFinite");
     464             : 
     465             :   Node* effect = graph()->start();
     466             :   Node* control = graph()->start();
     467           1 :   Node* context = UndefinedConstant();
     468             :   Node* frame_state = graph()->start();
     469           1 :   Node* p0 = Parameter(Type::Any(), 0);
     470           1 :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     471             :                                 context, frame_state, effect, control);
     472           1 :   Reduction r = Reduce(call);
     473             : 
     474           1 :   ASSERT_TRUE(r.Changed());
     475           5 :   EXPECT_THAT(r.replacement(), IsObjectIsFiniteNumber(p0));
     476             : }
     477             : 
     478             : // -----------------------------------------------------------------------------
     479             : // Number.isInteger
     480             : 
     481       15444 : TEST_F(JSCallReducerTest, NumberIsIntegerWithNumber) {
     482           1 :   Node* function = NumberFunction("isInteger");
     483             : 
     484             :   Node* effect = graph()->start();
     485             :   Node* control = graph()->start();
     486           1 :   Node* context = UndefinedConstant();
     487             :   Node* frame_state = graph()->start();
     488           1 :   Node* p0 = Parameter(Type::Any(), 0);
     489             :   Node* call =
     490           3 :       graph()->NewNode(javascript()->Call(3), function, UndefinedConstant(), p0,
     491             :                        context, frame_state, effect, control);
     492           1 :   Reduction r = Reduce(call);
     493             : 
     494           1 :   ASSERT_TRUE(r.Changed());
     495           5 :   EXPECT_THAT(r.replacement(), IsObjectIsInteger(p0));
     496             : }
     497             : 
     498             : // -----------------------------------------------------------------------------
     499             : // Number.isNaN
     500             : 
     501       15444 : TEST_F(JSCallReducerTest, NumberIsNaNWithNumber) {
     502           1 :   Node* function = NumberFunction("isNaN");
     503             : 
     504             :   Node* effect = graph()->start();
     505             :   Node* control = graph()->start();
     506           1 :   Node* context = UndefinedConstant();
     507             :   Node* frame_state = graph()->start();
     508           1 :   Node* p0 = Parameter(Type::Any(), 0);
     509             :   Node* call =
     510           3 :       graph()->NewNode(javascript()->Call(3), function, UndefinedConstant(), p0,
     511             :                        context, frame_state, effect, control);
     512           1 :   Reduction r = Reduce(call);
     513             : 
     514           1 :   ASSERT_TRUE(r.Changed());
     515           5 :   EXPECT_THAT(r.replacement(), IsObjectIsNaN(p0));
     516             : }
     517             : 
     518             : // -----------------------------------------------------------------------------
     519             : // Number.isSafeInteger
     520             : 
     521       15444 : TEST_F(JSCallReducerTest, NumberIsSafeIntegerWithIntegral32) {
     522           1 :   Node* function = NumberFunction("isSafeInteger");
     523             : 
     524             :   Node* effect = graph()->start();
     525             :   Node* control = graph()->start();
     526           1 :   Node* context = UndefinedConstant();
     527             :   Node* frame_state = graph()->start();
     528           1 :   Node* p0 = Parameter(Type::Any(), 0);
     529             :   Node* call =
     530           3 :       graph()->NewNode(javascript()->Call(3), function, UndefinedConstant(), p0,
     531             :                        context, frame_state, effect, control);
     532           1 :   Reduction r = Reduce(call);
     533             : 
     534           1 :   ASSERT_TRUE(r.Changed());
     535           5 :   EXPECT_THAT(r.replacement(), IsObjectIsSafeInteger(p0));
     536             : }
     537             : 
     538             : // -----------------------------------------------------------------------------
     539             : // isFinite
     540             : 
     541       15444 : TEST_F(JSCallReducerTest, GlobalIsFiniteWithNumber) {
     542           1 :   Node* function = GlobalFunction("isFinite");
     543             : 
     544             :   Node* effect = graph()->start();
     545             :   Node* control = graph()->start();
     546           1 :   Node* context = UndefinedConstant();
     547             :   Node* frame_state = graph()->start();
     548           1 :   Node* p0 = Parameter(Type::Any(), 0);
     549           1 :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     550             :                                 context, frame_state, effect, control);
     551           1 :   Reduction r = Reduce(call);
     552             : 
     553           1 :   ASSERT_TRUE(r.Changed());
     554           6 :   EXPECT_THAT(r.replacement(), IsNumberIsFinite(IsSpeculativeToNumber(p0)));
     555             : }
     556             : 
     557             : // -----------------------------------------------------------------------------
     558             : // isNaN
     559             : 
     560       15444 : TEST_F(JSCallReducerTest, GlobalIsNaN) {
     561           1 :   Node* function = GlobalFunction("isNaN");
     562             : 
     563             :   Node* effect = graph()->start();
     564             :   Node* control = graph()->start();
     565           1 :   Node* context = UndefinedConstant();
     566             :   Node* frame_state = graph()->start();
     567           1 :   Node* p0 = Parameter(Type::Any(), 0);
     568           1 :   Node* call = graph()->NewNode(Call(3), function, UndefinedConstant(), p0,
     569             :                                 context, frame_state, effect, control);
     570           1 :   Reduction r = Reduce(call);
     571             : 
     572           1 :   ASSERT_TRUE(r.Changed());
     573           6 :   EXPECT_THAT(r.replacement(), IsNumberIsNaN(IsSpeculativeToNumber(p0)));
     574             : }
     575             : 
     576             : // -----------------------------------------------------------------------------
     577             : // Number.parseInt
     578             : 
     579       15444 : TEST_F(JSCallReducerTest, NumberParseInt) {
     580           1 :   Node* function = NumberFunction("parseInt");
     581             : 
     582             :   Node* effect = graph()->start();
     583             :   Node* control = graph()->start();
     584           1 :   Node* context = UndefinedConstant();
     585             :   Node* frame_state = graph()->start();
     586           1 :   Node* p0 = Parameter(Type::Any(), 0);
     587           1 :   Node* p1 = Parameter(Type::Any(), 1);
     588           1 :   Node* call = graph()->NewNode(Call(4), function, UndefinedConstant(), p0, p1,
     589             :                                 context, frame_state, effect, control);
     590           1 :   Reduction r = Reduce(call);
     591             : 
     592           1 :   ASSERT_TRUE(r.Changed());
     593           6 :   EXPECT_THAT(r.replacement(), IsJSParseInt(p0, p1));
     594             : }
     595             : 
     596             : }  // namespace compiler
     597             : }  // namespace internal
     598        9264 : }  // namespace v8

Generated by: LCOV version 1.10