LCOV - code coverage report
Current view: top level - src/compiler - frame-states.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 57 74 77.0 %
Date: 2019-04-17 Functions: 10 12 83.3 %

          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/frame-states.h"
       6             : 
       7             : #include "src/base/functional.h"
       8             : #include "src/callable.h"
       9             : #include "src/compiler/graph.h"
      10             : #include "src/compiler/js-graph.h"
      11             : #include "src/compiler/node.h"
      12             : #include "src/handles-inl.h"
      13             : #include "src/objects-inl.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : namespace compiler {
      18             : 
      19           0 : size_t hash_value(OutputFrameStateCombine const& sc) {
      20    29743535 :   return base::hash_value(sc.parameter_);
      21             : }
      22             : 
      23             : 
      24          77 : std::ostream& operator<<(std::ostream& os, OutputFrameStateCombine const& sc) {
      25          77 :   if (sc.parameter_ == OutputFrameStateCombine::kInvalidIndex)
      26          77 :     return os << "Ignore";
      27           0 :   return os << "PokeAt(" << sc.parameter_ << ")";
      28             : }
      29             : 
      30             : 
      31     9085195 : bool operator==(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
      32     9005227 :   return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() &&
      33     9749072 :          lhs.state_combine() == rhs.state_combine() &&
      34     9085195 :          lhs.function_info() == rhs.function_info();
      35             : }
      36             : 
      37             : 
      38           0 : bool operator!=(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
      39           0 :   return !(lhs == rhs);
      40             : }
      41             : 
      42             : 
      43    29743792 : size_t hash_value(FrameStateInfo const& info) {
      44    59487053 :   return base::hash_combine(static_cast<int>(info.type()), info.bailout_id(),
      45    29743261 :                             info.state_combine());
      46             : }
      47             : 
      48             : 
      49          77 : std::ostream& operator<<(std::ostream& os, FrameStateType type) {
      50          77 :   switch (type) {
      51             :     case FrameStateType::kInterpretedFunction:
      52          77 :       os << "INTERPRETED_FRAME";
      53          77 :       break;
      54             :     case FrameStateType::kArgumentsAdaptor:
      55           0 :       os << "ARGUMENTS_ADAPTOR";
      56           0 :       break;
      57             :     case FrameStateType::kConstructStub:
      58           0 :       os << "CONSTRUCT_STUB";
      59           0 :       break;
      60             :     case FrameStateType::kBuiltinContinuation:
      61           0 :       os << "BUILTIN_CONTINUATION_FRAME";
      62           0 :       break;
      63             :     case FrameStateType::kJavaScriptBuiltinContinuation:
      64           0 :       os << "JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME";
      65           0 :       break;
      66             :     case FrameStateType::kJavaScriptBuiltinContinuationWithCatch:
      67           0 :       os << "JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME";
      68           0 :       break;
      69             :   }
      70          77 :   return os;
      71             : }
      72             : 
      73             : 
      74          77 : std::ostream& operator<<(std::ostream& os, FrameStateInfo const& info) {
      75         154 :   os << info.type() << ", " << info.bailout_id() << ", "
      76         154 :      << info.state_combine();
      77             :   Handle<SharedFunctionInfo> shared_info;
      78          77 :   if (info.shared_info().ToHandle(&shared_info)) {
      79         154 :     os << ", " << Brief(*shared_info);
      80             :   }
      81          77 :   return os;
      82             : }
      83             : 
      84             : namespace {
      85             : 
      86             : // Lazy deopt points where the frame state is assocated with a call get an
      87             : // additional parameter for the return result from the call. The return result
      88             : // is added by the deoptimizer and not explicitly specified in the frame state.
      89             : // Lazy deopt points which can catch exceptions further get an additional
      90             : // parameter, namely the exception thrown. The exception is also added by the
      91             : // deoptimizer.
      92        3075 : uint8_t DeoptimizerParameterCountFor(ContinuationFrameStateMode mode) {
      93        3075 :   switch (mode) {
      94             :     case ContinuationFrameStateMode::EAGER:
      95             :       return 0;
      96             :     case ContinuationFrameStateMode::LAZY:
      97        3075 :       return 1;
      98             :     case ContinuationFrameStateMode::LAZY_WITH_CATCH:
      99           0 :       return 2;
     100             :   }
     101           0 :   UNREACHABLE();
     102             : }
     103             : 
     104        9588 : Node* CreateBuiltinContinuationFrameStateCommon(
     105             :     JSGraph* jsgraph, FrameStateType frame_type, Builtins::Name name,
     106             :     Node* closure, Node* context, Node** parameters, int parameter_count,
     107             :     Node* outer_frame_state,
     108             :     Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>()) {
     109             :   Isolate* const isolate = jsgraph->isolate();
     110             :   Graph* const graph = jsgraph->graph();
     111             :   CommonOperatorBuilder* const common = jsgraph->common();
     112             : 
     113        9588 :   BailoutId bailout_id = Builtins::GetContinuationBailoutId(name);
     114        9588 :   Callable callable = Builtins::CallableFor(isolate, name);
     115             : 
     116             :   const Operator* op_param =
     117        9588 :       common->StateValues(parameter_count, SparseInputMask::Dense());
     118        9588 :   Node* params_node = graph->NewNode(op_param, parameter_count, parameters);
     119             : 
     120             :   const FrameStateFunctionInfo* state_info =
     121             :       common->CreateFrameStateFunctionInfo(frame_type, parameter_count, 0,
     122        9588 :                                            shared);
     123             :   const Operator* op = common->FrameState(
     124        9588 :       bailout_id, OutputFrameStateCombine::Ignore(), state_info);
     125             : 
     126        9588 :   Node* frame_state = graph->NewNode(
     127             :       op, params_node, jsgraph->EmptyStateValues(), jsgraph->EmptyStateValues(),
     128             :       context, closure, outer_frame_state);
     129             : 
     130        9588 :   return frame_state;
     131             : }
     132             : 
     133             : }  // namespace
     134             : 
     135        3075 : Node* CreateStubBuiltinContinuationFrameState(
     136             :     JSGraph* jsgraph, Builtins::Name name, Node* context,
     137             :     Node* const* parameters, int parameter_count, Node* outer_frame_state,
     138             :     ContinuationFrameStateMode mode) {
     139             :   Isolate* isolate = jsgraph->isolate();
     140        3075 :   Callable callable = Builtins::CallableFor(isolate, name);
     141             :   CallInterfaceDescriptor descriptor = callable.descriptor();
     142             : 
     143             :   std::vector<Node*> actual_parameters;
     144             :   // Stack parameters first. Depending on {mode}, final parameters are added
     145             :   // by the deoptimizer and aren't explicitly passed in the frame state.
     146             :   int stack_parameter_count =
     147        3075 :       descriptor.GetParameterCount() - DeoptimizerParameterCountFor(mode);
     148             :   // Reserving space in the vector, except for the case where
     149             :   // stack_parameter_count is -1.
     150        6150 :   actual_parameters.reserve(stack_parameter_count >= 0
     151        3075 :                                 ? stack_parameter_count +
     152             :                                       descriptor.GetRegisterParameterCount()
     153        3075 :                                 : 0);
     154        7271 :   for (int i = 0; i < stack_parameter_count; ++i) {
     155        2098 :     actual_parameters.push_back(
     156        4196 :         parameters[descriptor.GetRegisterParameterCount() + i]);
     157             :   }
     158             :   // Register parameters follow, context will be added by instruction selector
     159             :   // during FrameState translation.
     160        3075 :   for (int i = 0; i < descriptor.GetRegisterParameterCount(); ++i) {
     161           0 :     actual_parameters.push_back(parameters[i]);
     162             :   }
     163             : 
     164        6150 :   return CreateBuiltinContinuationFrameStateCommon(
     165             :       jsgraph, FrameStateType::kBuiltinContinuation, name,
     166             :       jsgraph->UndefinedConstant(), context, actual_parameters.data(),
     167        6150 :       static_cast<int>(actual_parameters.size()), outer_frame_state);
     168             : }
     169             : 
     170        6513 : Node* CreateJavaScriptBuiltinContinuationFrameState(
     171             :     JSGraph* jsgraph, const SharedFunctionInfoRef& shared, Builtins::Name name,
     172             :     Node* target, Node* context, Node* const* stack_parameters,
     173             :     int stack_parameter_count, Node* outer_frame_state,
     174             :     ContinuationFrameStateMode mode) {
     175             :   Isolate* const isolate = jsgraph->isolate();
     176        6513 :   Callable const callable = Builtins::CallableFor(isolate, name);
     177             : 
     178             :   // Depending on {mode}, final parameters are added by the deoptimizer
     179             :   // and aren't explicitly passed in the frame state.
     180             :   DCHECK_EQ(Builtins::GetStackParameterCount(name) + 1,  // add receiver
     181             :             stack_parameter_count + DeoptimizerParameterCountFor(mode));
     182             : 
     183        6513 :   Node* argc = jsgraph->Constant(Builtins::GetStackParameterCount(name));
     184             : 
     185             :   // Stack parameters first. They must be first because the receiver is expected
     186             :   // to be the second value in the translation when creating stack crawls
     187             :   // (e.g. Error.stack) of optimized JavaScript frames.
     188             :   std::vector<Node*> actual_parameters;
     189       65959 :   for (int i = 0; i < stack_parameter_count; ++i) {
     190       29723 :     actual_parameters.push_back(stack_parameters[i]);
     191             :   }
     192             : 
     193             :   // Register parameters follow stack paraemters. The context will be added by
     194             :   // instruction selector during FrameState translation.
     195        6513 :   actual_parameters.push_back(target);
     196       13026 :   actual_parameters.push_back(jsgraph->UndefinedConstant());
     197        6513 :   actual_parameters.push_back(argc);
     198             : 
     199       13026 :   return CreateBuiltinContinuationFrameStateCommon(
     200             :       jsgraph,
     201             :       mode == ContinuationFrameStateMode::LAZY_WITH_CATCH
     202             :           ? FrameStateType::kJavaScriptBuiltinContinuationWithCatch
     203             :           : FrameStateType::kJavaScriptBuiltinContinuation,
     204             :       name, target, context, &actual_parameters[0],
     205             :       static_cast<int>(actual_parameters.size()), outer_frame_state,
     206       13026 :       shared.object());
     207             : }
     208             : 
     209             : }  // namespace compiler
     210             : }  // namespace internal
     211      122004 : }  // namespace v8

Generated by: LCOV version 1.10