LCOV - code coverage report
Current view: top level - src/compiler - js-intrinsic-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 155 172 90.1 %
Date: 2019-04-19 Functions: 28 35 80.0 %

          Line data    Source code
       1             : // Copyright 2015 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 "src/compiler/js-intrinsic-lowering.h"
       6             : 
       7             : #include <stack>
       8             : 
       9             : #include "src/code-factory.h"
      10             : #include "src/compiler/access-builder.h"
      11             : #include "src/compiler/js-graph.h"
      12             : #include "src/compiler/linkage.h"
      13             : #include "src/compiler/node-matchers.h"
      14             : #include "src/compiler/node-properties.h"
      15             : #include "src/compiler/operator-properties.h"
      16             : #include "src/counters.h"
      17             : #include "src/objects-inl.h"
      18             : #include "src/objects/js-generator.h"
      19             : 
      20             : namespace v8 {
      21             : namespace internal {
      22             : namespace compiler {
      23             : 
      24      464446 : JSIntrinsicLowering::JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph)
      25      464446 :     : AdvancedReducer(editor), jsgraph_(jsgraph) {}
      26             : 
      27    33823534 : Reduction JSIntrinsicLowering::Reduce(Node* node) {
      28    33823534 :   if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange();
      29             :   const Runtime::Function* const f =
      30      385615 :       Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id());
      31      385615 :   if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange();
      32       21135 :   switch (f->function_id) {
      33             :     case Runtime::kInlineCreateIterResultObject:
      34        1974 :       return ReduceCreateIterResultObject(node);
      35             :     case Runtime::kInlineDeoptimizeNow:
      36        3881 :       return ReduceDeoptimizeNow(node);
      37             :     case Runtime::kInlineGeneratorClose:
      38         182 :       return ReduceGeneratorClose(node);
      39             :     case Runtime::kInlineCreateJSGeneratorObject:
      40        1307 :       return ReduceCreateJSGeneratorObject(node);
      41             :     case Runtime::kInlineAsyncFunctionAwaitCaught:
      42         205 :       return ReduceAsyncFunctionAwaitCaught(node);
      43             :     case Runtime::kInlineAsyncFunctionAwaitUncaught:
      44        2570 :       return ReduceAsyncFunctionAwaitUncaught(node);
      45             :     case Runtime::kInlineAsyncFunctionEnter:
      46        1256 :       return ReduceAsyncFunctionEnter(node);
      47             :     case Runtime::kInlineAsyncFunctionReject:
      48        1211 :       return ReduceAsyncFunctionReject(node);
      49             :     case Runtime::kInlineAsyncFunctionResolve:
      50        1118 :       return ReduceAsyncFunctionResolve(node);
      51             :     case Runtime::kInlineAsyncGeneratorAwaitCaught:
      52           5 :       return ReduceAsyncGeneratorAwaitCaught(node);
      53             :     case Runtime::kInlineAsyncGeneratorAwaitUncaught:
      54         214 :       return ReduceAsyncGeneratorAwaitUncaught(node);
      55             :     case Runtime::kInlineAsyncGeneratorReject:
      56         182 :       return ReduceAsyncGeneratorReject(node);
      57             :     case Runtime::kInlineAsyncGeneratorResolve:
      58         182 :       return ReduceAsyncGeneratorResolve(node);
      59             :     case Runtime::kInlineAsyncGeneratorYield:
      60          62 :       return ReduceAsyncGeneratorYield(node);
      61             :     case Runtime::kInlineGeneratorGetResumeMode:
      62        6528 :       return ReduceGeneratorGetResumeMode(node);
      63             :     case Runtime::kInlineIsArray:
      64          26 :       return ReduceIsInstanceType(node, JS_ARRAY_TYPE);
      65             :     case Runtime::kInlineIsTypedArray:
      66           1 :       return ReduceIsInstanceType(node, JS_TYPED_ARRAY_TYPE);
      67             :     case Runtime::kInlineIsJSReceiver:
      68          26 :       return ReduceIsJSReceiver(node);
      69             :     case Runtime::kInlineIsSmi:
      70          30 :       return ReduceIsSmi(node);
      71             :     case Runtime::kInlineToLength:
      72          36 :       return ReduceToLength(node);
      73             :     case Runtime::kInlineToObject:
      74           0 :       return ReduceToObject(node);
      75             :     case Runtime::kInlineToString:
      76          13 :       return ReduceToString(node);
      77             :     case Runtime::kInlineCall:
      78          40 :       return ReduceCall(node);
      79             :     default:
      80             :       break;
      81             :   }
      82             :   return NoChange();
      83             : }
      84             : 
      85             : 
      86        1974 : Reduction JSIntrinsicLowering::ReduceCreateIterResultObject(Node* node) {
      87        1974 :   Node* const value = NodeProperties::GetValueInput(node, 0);
      88        1974 :   Node* const done = NodeProperties::GetValueInput(node, 1);
      89        1974 :   Node* const context = NodeProperties::GetContextInput(node);
      90        1974 :   Node* const effect = NodeProperties::GetEffectInput(node);
      91             :   return Change(node, javascript()->CreateIterResultObject(), value, done,
      92        1974 :                 context, effect);
      93             : }
      94             : 
      95        3881 : Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
      96        3881 :   Node* const frame_state = NodeProperties::GetFrameStateInput(node);
      97        3881 :   Node* const effect = NodeProperties::GetEffectInput(node);
      98        3881 :   Node* const control = NodeProperties::GetControlInput(node);
      99             : 
     100             :   // TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
     101        7762 :   Node* deoptimize = graph()->NewNode(
     102             :       common()->Deoptimize(DeoptimizeKind::kEager,
     103             :                            DeoptimizeReason::kDeoptimizeNow, VectorSlotPair()),
     104             :       frame_state, effect, control);
     105        3881 :   NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
     106             :   Revisit(graph()->end());
     107             : 
     108        3881 :   node->TrimInputCount(0);
     109        3881 :   NodeProperties::ChangeOp(node, common()->Dead());
     110        3881 :   return Changed(node);
     111             : }
     112             : 
     113        1307 : Reduction JSIntrinsicLowering::ReduceCreateJSGeneratorObject(Node* node) {
     114        1307 :   Node* const closure = NodeProperties::GetValueInput(node, 0);
     115        1307 :   Node* const receiver = NodeProperties::GetValueInput(node, 1);
     116        1307 :   Node* const context = NodeProperties::GetContextInput(node);
     117        1307 :   Node* const effect = NodeProperties::GetEffectInput(node);
     118        1307 :   Node* const control = NodeProperties::GetControlInput(node);
     119        1307 :   Operator const* const op = javascript()->CreateGeneratorObject();
     120             :   Node* create_generator =
     121             :       graph()->NewNode(op, closure, receiver, context, effect, control);
     122             :   ReplaceWithValue(node, create_generator, create_generator);
     123        1307 :   return Changed(create_generator);
     124             : }
     125             : 
     126         182 : Reduction JSIntrinsicLowering::ReduceGeneratorClose(Node* node) {
     127         182 :   Node* const generator = NodeProperties::GetValueInput(node, 0);
     128         182 :   Node* const effect = NodeProperties::GetEffectInput(node);
     129         182 :   Node* const control = NodeProperties::GetControlInput(node);
     130         182 :   Node* const closed = jsgraph()->Constant(JSGeneratorObject::kGeneratorClosed);
     131         182 :   Node* const undefined = jsgraph()->UndefinedConstant();
     132             :   Operator const* const op = simplified()->StoreField(
     133         182 :       AccessBuilder::ForJSGeneratorObjectContinuation());
     134             : 
     135             :   ReplaceWithValue(node, undefined, node);
     136             :   NodeProperties::RemoveType(node);
     137         182 :   return Change(node, op, generator, closed, effect, control);
     138             : }
     139             : 
     140         205 : Reduction JSIntrinsicLowering::ReduceAsyncFunctionAwaitCaught(Node* node) {
     141             :   return Change(
     142             :       node,
     143         410 :       Builtins::CallableFor(isolate(), Builtins::kAsyncFunctionAwaitCaught), 0);
     144             : }
     145             : 
     146        2570 : Reduction JSIntrinsicLowering::ReduceAsyncFunctionAwaitUncaught(Node* node) {
     147             :   return Change(
     148             :       node,
     149        5140 :       Builtins::CallableFor(isolate(), Builtins::kAsyncFunctionAwaitUncaught),
     150        5140 :       0);
     151             : }
     152             : 
     153        1256 : Reduction JSIntrinsicLowering::ReduceAsyncFunctionEnter(Node* node) {
     154        1256 :   NodeProperties::ChangeOp(node, javascript()->AsyncFunctionEnter());
     155        1256 :   return Changed(node);
     156             : }
     157             : 
     158        1211 : Reduction JSIntrinsicLowering::ReduceAsyncFunctionReject(Node* node) {
     159             :   RelaxControls(node);
     160        1211 :   NodeProperties::ChangeOp(node, javascript()->AsyncFunctionReject());
     161        1211 :   return Changed(node);
     162             : }
     163             : 
     164        1118 : Reduction JSIntrinsicLowering::ReduceAsyncFunctionResolve(Node* node) {
     165             :   RelaxControls(node);
     166        1118 :   NodeProperties::ChangeOp(node, javascript()->AsyncFunctionResolve());
     167        1118 :   return Changed(node);
     168             : }
     169             : 
     170           5 : Reduction JSIntrinsicLowering::ReduceAsyncGeneratorAwaitCaught(Node* node) {
     171             :   return Change(
     172             :       node,
     173          10 :       Builtins::CallableFor(isolate(), Builtins::kAsyncGeneratorAwaitCaught),
     174          10 :       0);
     175             : }
     176             : 
     177         214 : Reduction JSIntrinsicLowering::ReduceAsyncGeneratorAwaitUncaught(Node* node) {
     178             :   return Change(
     179             :       node,
     180         428 :       Builtins::CallableFor(isolate(), Builtins::kAsyncGeneratorAwaitUncaught),
     181         428 :       0);
     182             : }
     183             : 
     184         182 : Reduction JSIntrinsicLowering::ReduceAsyncGeneratorReject(Node* node) {
     185             :   return Change(
     186         364 :       node, Builtins::CallableFor(isolate(), Builtins::kAsyncGeneratorReject),
     187         364 :       0);
     188             : }
     189             : 
     190         182 : Reduction JSIntrinsicLowering::ReduceAsyncGeneratorResolve(Node* node) {
     191             :   return Change(
     192         364 :       node, Builtins::CallableFor(isolate(), Builtins::kAsyncGeneratorResolve),
     193         364 :       0);
     194             : }
     195             : 
     196          62 : Reduction JSIntrinsicLowering::ReduceAsyncGeneratorYield(Node* node) {
     197             :   return Change(
     198         124 :       node, Builtins::CallableFor(isolate(), Builtins::kAsyncGeneratorYield),
     199         124 :       0);
     200             : }
     201             : 
     202        6528 : Reduction JSIntrinsicLowering::ReduceGeneratorGetResumeMode(Node* node) {
     203        6528 :   Node* const generator = NodeProperties::GetValueInput(node, 0);
     204        6528 :   Node* const effect = NodeProperties::GetEffectInput(node);
     205        6528 :   Node* const control = NodeProperties::GetControlInput(node);
     206             :   Operator const* const op =
     207        6528 :       simplified()->LoadField(AccessBuilder::ForJSGeneratorObjectResumeMode());
     208             : 
     209        6528 :   return Change(node, op, generator, effect, control);
     210             : }
     211             : 
     212          27 : Reduction JSIntrinsicLowering::ReduceIsInstanceType(
     213             :     Node* node, InstanceType instance_type) {
     214             :   // if (%_IsSmi(value)) {
     215             :   //   return false;
     216             :   // } else {
     217             :   //   return %_GetInstanceType(%_GetMap(value)) == instance_type;
     218             :   // }
     219          27 :   Node* value = NodeProperties::GetValueInput(node, 0);
     220          27 :   Node* effect = NodeProperties::GetEffectInput(node);
     221          27 :   Node* control = NodeProperties::GetControlInput(node);
     222             : 
     223          27 :   Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
     224          27 :   Node* branch = graph()->NewNode(common()->Branch(), check, control);
     225             : 
     226          27 :   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
     227             :   Node* etrue = effect;
     228          27 :   Node* vtrue = jsgraph()->FalseConstant();
     229             : 
     230          27 :   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
     231             :   Node* efalse = effect;
     232             :   Node* map = efalse =
     233          54 :       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), value,
     234             :                        efalse, if_false);
     235          27 :   Node* map_instance_type = efalse = graph()->NewNode(
     236          54 :       simplified()->LoadField(AccessBuilder::ForMapInstanceType()), map, efalse,
     237             :       if_false);
     238             :   Node* vfalse =
     239          27 :       graph()->NewNode(simplified()->NumberEqual(), map_instance_type,
     240             :                        jsgraph()->Constant(instance_type));
     241             : 
     242          27 :   Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
     243             : 
     244             :   // Replace all effect uses of {node} with the {ephi}.
     245          27 :   Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
     246             :   ReplaceWithValue(node, node, ephi, merge);
     247             : 
     248             :   // Turn the {node} into a Phi.
     249             :   return Change(node, common()->Phi(MachineRepresentation::kTagged, 2), vtrue,
     250          27 :                 vfalse, merge);
     251             : }
     252             : 
     253             : 
     254          26 : Reduction JSIntrinsicLowering::ReduceIsJSReceiver(Node* node) {
     255          26 :   return Change(node, simplified()->ObjectIsReceiver());
     256             : }
     257             : 
     258             : 
     259          30 : Reduction JSIntrinsicLowering::ReduceIsSmi(Node* node) {
     260          30 :   return Change(node, simplified()->ObjectIsSmi());
     261             : }
     262             : 
     263          56 : Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
     264             :   // Replace all effect uses of {node} with the effect dependency.
     265             :   RelaxEffectsAndControls(node);
     266             :   // Remove the inputs corresponding to context, effect and control.
     267          56 :   NodeProperties::RemoveNonValueInputs(node);
     268             :   // Finally update the operator to the new one.
     269          56 :   NodeProperties::ChangeOp(node, op);
     270          56 :   return Changed(node);
     271             : }
     272             : 
     273             : 
     274          36 : Reduction JSIntrinsicLowering::ReduceToLength(Node* node) {
     275          36 :   NodeProperties::ChangeOp(node, javascript()->ToLength());
     276          36 :   return Changed(node);
     277             : }
     278             : 
     279             : 
     280           0 : Reduction JSIntrinsicLowering::ReduceToObject(Node* node) {
     281           0 :   NodeProperties::ChangeOp(node, javascript()->ToObject());
     282           0 :   return Changed(node);
     283             : }
     284             : 
     285             : 
     286          13 : Reduction JSIntrinsicLowering::ReduceToString(Node* node) {
     287             :   // ToString is unnecessary if the input is a string.
     288          13 :   HeapObjectMatcher m(NodeProperties::GetValueInput(node, 0));
     289          18 :   if (m.HasValue() && m.Value()->IsString()) {
     290             :     ReplaceWithValue(node, m.node());
     291             :     return Replace(m.node());
     292             :   }
     293          12 :   NodeProperties::ChangeOp(node, javascript()->ToString());
     294             :   return Changed(node);
     295             : }
     296             : 
     297             : 
     298          40 : Reduction JSIntrinsicLowering::ReduceCall(Node* node) {
     299          40 :   size_t const arity = CallRuntimeParametersOf(node->op()).arity();
     300          80 :   NodeProperties::ChangeOp(node, javascript()->Call(arity));
     301          40 :   return Changed(node);
     302             : }
     303             : 
     304           0 : Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
     305             :                                       Node* b) {
     306             :   RelaxControls(node);
     307           0 :   node->ReplaceInput(0, a);
     308           0 :   node->ReplaceInput(1, b);
     309           0 :   node->TrimInputCount(2);
     310           0 :   NodeProperties::ChangeOp(node, op);
     311           0 :   return Changed(node);
     312             : }
     313             : 
     314             : 
     315        6555 : Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
     316             :                                       Node* b, Node* c) {
     317             :   RelaxControls(node);
     318        6555 :   node->ReplaceInput(0, a);
     319        6555 :   node->ReplaceInput(1, b);
     320        6555 :   node->ReplaceInput(2, c);
     321        6555 :   node->TrimInputCount(3);
     322        6555 :   NodeProperties::ChangeOp(node, op);
     323        6555 :   return Changed(node);
     324             : }
     325             : 
     326             : 
     327        2156 : Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
     328             :                                       Node* b, Node* c, Node* d) {
     329             :   RelaxControls(node);
     330        2156 :   node->ReplaceInput(0, a);
     331        2156 :   node->ReplaceInput(1, b);
     332        2156 :   node->ReplaceInput(2, c);
     333        2156 :   node->ReplaceInput(3, d);
     334        2156 :   node->TrimInputCount(4);
     335        2156 :   NodeProperties::ChangeOp(node, op);
     336        2156 :   return Changed(node);
     337             : }
     338             : 
     339             : 
     340        3420 : Reduction JSIntrinsicLowering::Change(Node* node, Callable const& callable,
     341             :                                       int stack_parameter_count) {
     342        3420 :   auto call_descriptor = Linkage::GetStubCallDescriptor(
     343        3420 :       graph()->zone(), callable.descriptor(), stack_parameter_count,
     344        3420 :       CallDescriptor::kNeedsFrameState, node->op()->properties());
     345        6840 :   node->InsertInput(graph()->zone(), 0,
     346        3420 :                     jsgraph()->HeapConstant(callable.code()));
     347        3420 :   NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
     348        3420 :   return Changed(node);
     349             : }
     350             : 
     351             : 
     352           0 : Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); }
     353             : 
     354             : 
     355           0 : Isolate* JSIntrinsicLowering::isolate() const { return jsgraph()->isolate(); }
     356             : 
     357             : 
     358           0 : CommonOperatorBuilder* JSIntrinsicLowering::common() const {
     359           0 :   return jsgraph()->common();
     360             : }
     361             : 
     362           0 : JSOperatorBuilder* JSIntrinsicLowering::javascript() const {
     363        6954 :   return jsgraph_->javascript();
     364             : }
     365             : 
     366           0 : SimplifiedOperatorBuilder* JSIntrinsicLowering::simplified() const {
     367           0 :   return jsgraph()->simplified();
     368             : }
     369             : 
     370             : }  // namespace compiler
     371             : }  // namespace internal
     372      122036 : }  // namespace v8

Generated by: LCOV version 1.10