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};
85
86class FrameStateFunctionInfo {
87 public:
88  FrameStateFunctionInfo(FrameStateType type, int parameter_count,
89                         int local_count,
90                         Handle<SharedFunctionInfo> shared_info)
91      : type_(type),
92        parameter_count_(parameter_count),
93        local_count_(local_count),
94        shared_info_(shared_info) {}
95
96  int local_count() const { return local_count_; }
97  int parameter_count() const { return parameter_count_; }
98  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
99  FrameStateType type() const { return type_; }
100
101  static bool IsJSFunctionType(FrameStateType type) {
102    return type == FrameStateType::kJavaScriptFunction ||
103           type == FrameStateType::kInterpretedFunction;
104  }
105
106 private:
107  FrameStateType const type_;
108  int const parameter_count_;
109  int const local_count_;
110  Handle<SharedFunctionInfo> const shared_info_;
111};
112
113
114class FrameStateInfo final {
115 public:
116  FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine,
117                 const FrameStateFunctionInfo* info)
118      : bailout_id_(bailout_id),
119        frame_state_combine_(state_combine),
120        info_(info) {}
121
122  FrameStateType type() const {
123    return info_ == nullptr ? FrameStateType::kJavaScriptFunction
124                            : info_->type();
125  }
126  BailoutId bailout_id() const { return bailout_id_; }
127  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
128  MaybeHandle<SharedFunctionInfo> shared_info() const {
129    return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
130                            : info_->shared_info();
131  }
132  int parameter_count() const {
133    return info_ == nullptr ? 0 : info_->parameter_count();
134  }
135  int local_count() const {
136    return info_ == nullptr ? 0 : info_->local_count();
137  }
138  const FrameStateFunctionInfo* function_info() const { return info_; }
139
140 private:
141  BailoutId const bailout_id_;
142  OutputFrameStateCombine const frame_state_combine_;
143  const FrameStateFunctionInfo* const info_;
144};
145
146bool operator==(FrameStateInfo const&, FrameStateInfo const&);
147bool operator!=(FrameStateInfo const&, FrameStateInfo const&);
148
149size_t hash_value(FrameStateInfo const&);
150
151std::ostream& operator<<(std::ostream&, FrameStateInfo const&);
152
153static const int kFrameStateParametersInput = 0;
154static const int kFrameStateLocalsInput = 1;
155static const int kFrameStateStackInput = 2;
156static const int kFrameStateContextInput = 3;
157static const int kFrameStateFunctionInput = 4;
158static const int kFrameStateOuterStateInput = 5;
159static const int kFrameStateInputCount = kFrameStateOuterStateInput + 1;
160
161}  // namespace compiler
162}  // namespace internal
163}  // namespace v8
164
165#endif  // V8_COMPILER_FRAME_STATES_H_
166