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#ifndef V8_COMPILER_FRAME_STATES_H_
6#define V8_COMPILER_FRAME_STATES_H_
7
8#include "src/handles.h"
9#include "src/utils.h"
10
11namespace v8 {
12namespace internal {
13
14// Forward declarations.
15class SharedFunctionInfo;
16
17namespace compiler {
18
19// Flag that describes how to combine the current environment with
20// the output of a node to obtain a framestate for lazy bailout.
21class OutputFrameStateCombine {
22 public:
23  enum Kind {
24    kPushOutput,  // Push the output on the expression stack.
25    kPokeAt       // Poke at the given environment location,
26                  // counting from the top of the stack.
27  };
28
29  static OutputFrameStateCombine Ignore() {
30    return OutputFrameStateCombine(kPushOutput, 0);
31  }
32  static OutputFrameStateCombine Push(size_t count = 1) {
33    return OutputFrameStateCombine(kPushOutput, count);
34  }
35  static OutputFrameStateCombine PokeAt(size_t index) {
36    return OutputFrameStateCombine(kPokeAt, index);
37  }
38
39  Kind kind() const { return kind_; }
40  size_t GetPushCount() const {
41    DCHECK_EQ(kPushOutput, kind());
42    return parameter_;
43  }
44  size_t GetOffsetToPokeAt() const {
45    DCHECK_EQ(kPokeAt, kind());
46    return parameter_;
47  }
48
49  bool IsOutputIgnored() const {
50    return kind_ == kPushOutput && parameter_ == 0;
51  }
52
53  size_t ConsumedOutputCount() const {
54    return kind_ == kPushOutput ? GetPushCount() : 1;
55  }
56
57  bool operator==(OutputFrameStateCombine const& other) const {
58    return kind_ == other.kind_ && parameter_ == other.parameter_;
59  }
60  bool operator!=(OutputFrameStateCombine const& other) const {
61    return !(*this == other);
62  }
63
64  friend size_t hash_value(OutputFrameStateCombine const&);
65  friend std::ostream& operator<<(std::ostream&,
66                                  OutputFrameStateCombine const&);
67
68 private:
69  OutputFrameStateCombine(Kind kind, size_t parameter)
70      : kind_(kind), parameter_(parameter) {}
71
72  Kind const kind_;
73  size_t const parameter_;
74};
75
76
77// The type of stack frame that a FrameState node represents.
78enum class FrameStateType {
79  kJavaScriptFunction,   // Represents an unoptimized JavaScriptFrame.
80  kInterpretedFunction,  // Represents an InterpretedFrame.
81  kArgumentsAdaptor,     // Represents an ArgumentsAdaptorFrame.
82  kTailCallerFunction,   // Represents a frame removed by tail call elimination.
83  kConstructStub,        // Represents a ConstructStubFrame.
84  kGetterStub,           // Represents a GetterStubFrame.
85  kSetterStub            // Represents a SetterStubFrame.
86};
87
88class FrameStateFunctionInfo {
89 public:
90  FrameStateFunctionInfo(FrameStateType type, int parameter_count,
91                         int local_count,
92                         Handle<SharedFunctionInfo> shared_info)
93      : type_(type),
94        parameter_count_(parameter_count),
95        local_count_(local_count),
96        shared_info_(shared_info) {}
97
98  int local_count() const { return local_count_; }
99  int parameter_count() const { return parameter_count_; }
100  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
101  FrameStateType type() const { return type_; }
102
103  static bool IsJSFunctionType(FrameStateType type) {
104    return type == FrameStateType::kJavaScriptFunction ||
105           type == FrameStateType::kInterpretedFunction;
106  }
107
108 private:
109  FrameStateType const type_;
110  int const parameter_count_;
111  int const local_count_;
112  Handle<SharedFunctionInfo> const shared_info_;
113};
114
115
116class FrameStateInfo final {
117 public:
118  FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine,
119                 const FrameStateFunctionInfo* info)
120      : bailout_id_(bailout_id),
121        frame_state_combine_(state_combine),
122        info_(info) {}
123
124  FrameStateType type() const {
125    return info_ == nullptr ? FrameStateType::kJavaScriptFunction
126                            : info_->type();
127  }
128  BailoutId bailout_id() const { return bailout_id_; }
129  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
130  MaybeHandle<SharedFunctionInfo> shared_info() const {
131    return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
132                            : info_->shared_info();
133  }
134  int parameter_count() const {
135    return info_ == nullptr ? 0 : info_->parameter_count();
136  }
137  int local_count() const {
138    return info_ == nullptr ? 0 : info_->local_count();
139  }
140  const FrameStateFunctionInfo* function_info() const { return info_; }
141
142 private:
143  BailoutId const bailout_id_;
144  OutputFrameStateCombine const frame_state_combine_;
145  const FrameStateFunctionInfo* const info_;
146};
147
148bool operator==(FrameStateInfo const&, FrameStateInfo const&);
149bool operator!=(FrameStateInfo const&, FrameStateInfo const&);
150
151size_t hash_value(FrameStateInfo const&);
152
153std::ostream& operator<<(std::ostream&, FrameStateInfo const&);
154
155static const int kFrameStateParametersInput = 0;
156static const int kFrameStateLocalsInput = 1;
157static const int kFrameStateStackInput = 2;
158static const int kFrameStateContextInput = 3;
159static const int kFrameStateFunctionInput = 4;
160static const int kFrameStateOuterStateInput = 5;
161static const int kFrameStateInputCount = kFrameStateOuterStateInput + 1;
162
163}  // namespace compiler
164}  // namespace internal
165}  // namespace v8
166
167#endif  // V8_COMPILER_FRAME_STATES_H_
168