frame-states.h 5.14 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_FRAME_STATES_H_
#define V8_COMPILER_FRAME_STATES_H_

8 9
#include "src/handles.h"
#include "src/utils.h"
10 11 12

namespace v8 {
namespace internal {
13 14 15 16

// Forward declarations.
class SharedFunctionInfo;

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
namespace compiler {

// Flag that describes how to combine the current environment with
// the output of a node to obtain a framestate for lazy bailout.
class OutputFrameStateCombine {
 public:
  enum Kind {
    kPushOutput,  // Push the output on the expression stack.
    kPokeAt       // Poke at the given environment location,
                  // counting from the top of the stack.
  };

  static OutputFrameStateCombine Ignore() {
    return OutputFrameStateCombine(kPushOutput, 0);
  }
  static OutputFrameStateCombine Push(size_t count = 1) {
    return OutputFrameStateCombine(kPushOutput, count);
  }
  static OutputFrameStateCombine PokeAt(size_t index) {
    return OutputFrameStateCombine(kPokeAt, index);
  }

  Kind kind() const { return kind_; }
  size_t GetPushCount() const {
    DCHECK_EQ(kPushOutput, kind());
    return parameter_;
  }
  size_t GetOffsetToPokeAt() const {
    DCHECK_EQ(kPokeAt, kind());
    return parameter_;
  }

  bool IsOutputIgnored() const {
    return kind_ == kPushOutput && parameter_ == 0;
  }

  size_t ConsumedOutputCount() const {
    return kind_ == kPushOutput ? GetPushCount() : 1;
  }

  bool operator==(OutputFrameStateCombine const& other) const {
    return kind_ == other.kind_ && parameter_ == other.parameter_;
  }
  bool operator!=(OutputFrameStateCombine const& other) const {
    return !(*this == other);
  }

  friend size_t hash_value(OutputFrameStateCombine const&);
  friend std::ostream& operator<<(std::ostream&,
                                  OutputFrameStateCombine const&);

 private:
  OutputFrameStateCombine(Kind kind, size_t parameter)
      : kind_(kind), parameter_(parameter) {}

  Kind const kind_;
  size_t const parameter_;
};


// The type of stack frame that a FrameState node represents.
78
enum class FrameStateType {
79 80 81
  kJavaScriptFunction,   // Represents an unoptimized JavaScriptFrame.
  kInterpretedFunction,  // Represents an InterpretedFrame.
  kArgumentsAdaptor,     // Represents an ArgumentsAdaptorFrame.
82
  kTailCallerFunction,   // Represents a frame removed by tail call elimination.
83
  kConstructStub         // Represents a ConstructStubFrame.
84 85
};

86
class FrameStateFunctionInfo {
87
 public:
88 89
  FrameStateFunctionInfo(FrameStateType type, int parameter_count,
                         int local_count,
90
                         Handle<SharedFunctionInfo> shared_info)
91
      : type_(type),
92 93
        parameter_count_(parameter_count),
        local_count_(local_count),
94
        shared_info_(shared_info) {}
95

96 97 98
  int local_count() const { return local_count_; }
  int parameter_count() const { return parameter_count_; }
  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
99
  FrameStateType type() const { return type_; }
100

101 102 103 104 105
  static bool IsJSFunctionType(FrameStateType type) {
    return type == FrameStateType::kJavaScriptFunction ||
           type == FrameStateType::kInterpretedFunction;
  }

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
 private:
  FrameStateType const type_;
  int const parameter_count_;
  int const local_count_;
  Handle<SharedFunctionInfo> const shared_info_;
};


class FrameStateInfo final {
 public:
  FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine,
                 const FrameStateFunctionInfo* info)
      : bailout_id_(bailout_id),
        frame_state_combine_(state_combine),
        info_(info) {}

  FrameStateType type() const {
    return info_ == nullptr ? FrameStateType::kJavaScriptFunction
                            : info_->type();
  }
126 127
  BailoutId bailout_id() const { return bailout_id_; }
  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
128 129 130 131 132 133 134 135 136 137 138
  MaybeHandle<SharedFunctionInfo> shared_info() const {
    return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
                            : info_->shared_info();
  }
  int parameter_count() const {
    return info_ == nullptr ? 0 : info_->parameter_count();
  }
  int local_count() const {
    return info_ == nullptr ? 0 : info_->local_count();
  }
  const FrameStateFunctionInfo* function_info() const { return info_; }
139 140

 private:
141 142
  BailoutId const bailout_id_;
  OutputFrameStateCombine const frame_state_combine_;
143
  const FrameStateFunctionInfo* const info_;
144 145
};

146 147
bool operator==(FrameStateInfo const&, FrameStateInfo const&);
bool operator!=(FrameStateInfo const&, FrameStateInfo const&);
148

149
size_t hash_value(FrameStateInfo const&);
150

151
std::ostream& operator<<(std::ostream&, FrameStateInfo const&);
152

153 154 155 156 157 158 159
static const int kFrameStateParametersInput = 0;
static const int kFrameStateLocalsInput = 1;
static const int kFrameStateStackInput = 2;
static const int kFrameStateContextInput = 3;
static const int kFrameStateFunctionInput = 4;
static const int kFrameStateOuterStateInput = 5;
static const int kFrameStateInputCount = kFrameStateOuterStateInput + 1;
160 161 162 163 164 165

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_FRAME_STATES_H_