1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_COMPILER_FRAME_STATES_H_
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_COMPILER_FRAME_STATES_H_
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/handles.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/utils.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 {
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal {
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations.
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SharedFunctionInfo;
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace compiler {
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Flag that describes how to combine the current environment with
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// the output of a node to obtain a framestate for lazy bailout.
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutputFrameStateCombine {
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Kind {
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kPushOutput,  // Push the output on the expression stack.
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kPokeAt       // Poke at the given environment location,
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  // counting from the top of the stack.
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static OutputFrameStateCombine Ignore() {
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return OutputFrameStateCombine(kPushOutput, 0);
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static OutputFrameStateCombine Push(size_t count = 1) {
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return OutputFrameStateCombine(kPushOutput, count);
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static OutputFrameStateCombine PokeAt(size_t index) {
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return OutputFrameStateCombine(kPokeAt, index);
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Kind kind() const { return kind_; }
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t GetPushCount() const {
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(kPushOutput, kind());
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return parameter_;
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t GetOffsetToPokeAt() const {
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(kPokeAt, kind());
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return parameter_;
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsOutputIgnored() const {
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return kind_ == kPushOutput && parameter_ == 0;
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t ConsumedOutputCount() const {
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return kind_ == kPushOutput ? GetPushCount() : 1;
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool operator==(OutputFrameStateCombine const& other) const {
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return kind_ == other.kind_ && parameter_ == other.parameter_;
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool operator!=(OutputFrameStateCombine const& other) const {
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return !(*this == other);
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  friend size_t hash_value(OutputFrameStateCombine const&);
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  friend std::ostream& operator<<(std::ostream&,
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  OutputFrameStateCombine const&);
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OutputFrameStateCombine(Kind kind, size_t parameter)
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : kind_(kind), parameter_(parameter) {}
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Kind const kind_;
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t const parameter_;
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The type of stack frame that a FrameState node represents.
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum class FrameStateType {
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kJavaScriptFunction,   // Represents an unoptimized JavaScriptFrame.
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kInterpretedFunction,  // Represents an InterpretedFrame.
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  kArgumentsAdaptor,     // Represents an ArgumentsAdaptorFrame.
823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  kTailCallerFunction,   // Represents a frame removed by tail call elimination.
83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  kConstructStub,        // Represents a ConstructStubFrame.
84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  kGetterStub,           // Represents a GetterStubFrame.
85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  kSetterStub            // Represents a SetterStubFrame.
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FrameStateFunctionInfo {
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameStateFunctionInfo(FrameStateType type, int parameter_count,
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         int local_count,
92109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                         Handle<SharedFunctionInfo> shared_info)
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : type_(type),
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        parameter_count_(parameter_count),
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        local_count_(local_count),
96109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        shared_info_(shared_info) {}
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int local_count() const { return local_count_; }
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int parameter_count() const { return parameter_count_; }
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameStateType type() const { return type_; }
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static bool IsJSFunctionType(FrameStateType type) {
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return type == FrameStateType::kJavaScriptFunction ||
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           type == FrameStateType::kInterpretedFunction;
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameStateType const type_;
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int const parameter_count_;
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int const local_count_;
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<SharedFunctionInfo> const shared_info_;
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FrameStateInfo final {
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine,
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 const FrameStateFunctionInfo* info)
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : bailout_id_(bailout_id),
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_state_combine_(state_combine),
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        info_(info) {}
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameStateType type() const {
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return info_ == nullptr ? FrameStateType::kJavaScriptFunction
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            : info_->type();
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId bailout_id() const { return bailout_id_; }
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaybeHandle<SharedFunctionInfo> shared_info() const {
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            : info_->shared_info();
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int parameter_count() const {
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return info_ == nullptr ? 0 : info_->parameter_count();
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int local_count() const {
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return info_ == nullptr ? 0 : info_->local_count();
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const FrameStateFunctionInfo* function_info() const { return info_; }
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId const bailout_id_;
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OutputFrameStateCombine const frame_state_combine_;
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const FrameStateFunctionInfo* const info_;
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool operator==(FrameStateInfo const&, FrameStateInfo const&);
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool operator!=(FrameStateInfo const&, FrameStateInfo const&);
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochsize_t hash_value(FrameStateInfo const&);
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream&, FrameStateInfo const&);
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kFrameStateParametersInput = 0;
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kFrameStateLocalsInput = 1;
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kFrameStateStackInput = 2;
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kFrameStateContextInput = 3;
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kFrameStateFunctionInput = 4;
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kFrameStateOuterStateInput = 5;
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kFrameStateInputCount = kFrameStateOuterStateInput + 1;
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace compiler
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_COMPILER_FRAME_STATES_H_
168