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 
11 namespace v8 {
12 namespace internal {
13 
14 // Forward declarations.
15 class SharedFunctionInfo;
16 
17 namespace 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.
21 class 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 
Ignore()29   static OutputFrameStateCombine Ignore() {
30     return OutputFrameStateCombine(kPushOutput, 0);
31   }
32   static OutputFrameStateCombine Push(size_t count = 1) {
33     return OutputFrameStateCombine(kPushOutput, count);
34   }
PokeAt(size_t index)35   static OutputFrameStateCombine PokeAt(size_t index) {
36     return OutputFrameStateCombine(kPokeAt, index);
37   }
38 
kind()39   Kind kind() const { return kind_; }
GetPushCount()40   size_t GetPushCount() const {
41     DCHECK_EQ(kPushOutput, kind());
42     return parameter_;
43   }
GetOffsetToPokeAt()44   size_t GetOffsetToPokeAt() const {
45     DCHECK_EQ(kPokeAt, kind());
46     return parameter_;
47   }
48 
IsOutputIgnored()49   bool IsOutputIgnored() const {
50     return kind_ == kPushOutput && parameter_ == 0;
51   }
52 
ConsumedOutputCount()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:
OutputFrameStateCombine(Kind kind,size_t parameter)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.
78 enum class FrameStateType {
79   kJavaScriptFunction,   // Represents an unoptimized JavaScriptFrame.
80   kInterpretedFunction,  // Represents an InterpretedFrame.
81   kArgumentsAdaptor,     // Represents an ArgumentsAdaptorFrame.
82   kConstructStub         // Represents a ConstructStubFrame.
83 };
84 
85 
86 enum ContextCallingMode {
87   CALL_MAINTAINS_NATIVE_CONTEXT,
88   CALL_CHANGES_NATIVE_CONTEXT
89 };
90 
91 
92 class FrameStateFunctionInfo {
93  public:
FrameStateFunctionInfo(FrameStateType type,int parameter_count,int local_count,Handle<SharedFunctionInfo> shared_info,ContextCallingMode context_calling_mode)94   FrameStateFunctionInfo(FrameStateType type, int parameter_count,
95                          int local_count,
96                          Handle<SharedFunctionInfo> shared_info,
97                          ContextCallingMode context_calling_mode)
98       : type_(type),
99         parameter_count_(parameter_count),
100         local_count_(local_count),
101         shared_info_(shared_info),
102         context_calling_mode_(context_calling_mode) {}
103 
local_count()104   int local_count() const { return local_count_; }
parameter_count()105   int parameter_count() const { return parameter_count_; }
shared_info()106   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
type()107   FrameStateType type() const { return type_; }
context_calling_mode()108   ContextCallingMode context_calling_mode() const {
109     return context_calling_mode_;
110   }
111 
IsJSFunctionType(FrameStateType type)112   static bool IsJSFunctionType(FrameStateType type) {
113     return type == FrameStateType::kJavaScriptFunction ||
114            type == FrameStateType::kInterpretedFunction;
115   }
116 
117  private:
118   FrameStateType const type_;
119   int const parameter_count_;
120   int const local_count_;
121   Handle<SharedFunctionInfo> const shared_info_;
122   ContextCallingMode context_calling_mode_;
123 };
124 
125 
126 class FrameStateInfo final {
127  public:
FrameStateInfo(BailoutId bailout_id,OutputFrameStateCombine state_combine,const FrameStateFunctionInfo * info)128   FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine,
129                  const FrameStateFunctionInfo* info)
130       : bailout_id_(bailout_id),
131         frame_state_combine_(state_combine),
132         info_(info) {}
133 
type()134   FrameStateType type() const {
135     return info_ == nullptr ? FrameStateType::kJavaScriptFunction
136                             : info_->type();
137   }
bailout_id()138   BailoutId bailout_id() const { return bailout_id_; }
state_combine()139   OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
shared_info()140   MaybeHandle<SharedFunctionInfo> shared_info() const {
141     return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
142                             : info_->shared_info();
143   }
parameter_count()144   int parameter_count() const {
145     return info_ == nullptr ? 0 : info_->parameter_count();
146   }
local_count()147   int local_count() const {
148     return info_ == nullptr ? 0 : info_->local_count();
149   }
function_info()150   const FrameStateFunctionInfo* function_info() const { return info_; }
151 
152  private:
153   BailoutId const bailout_id_;
154   OutputFrameStateCombine const frame_state_combine_;
155   const FrameStateFunctionInfo* const info_;
156 };
157 
158 bool operator==(FrameStateInfo const&, FrameStateInfo const&);
159 bool operator!=(FrameStateInfo const&, FrameStateInfo const&);
160 
161 size_t hash_value(FrameStateInfo const&);
162 
163 std::ostream& operator<<(std::ostream&, FrameStateInfo const&);
164 
165 static const int kFrameStateParametersInput = 0;
166 static const int kFrameStateLocalsInput = 1;
167 static const int kFrameStateStackInput = 2;
168 static const int kFrameStateContextInput = 3;
169 static const int kFrameStateFunctionInput = 4;
170 static const int kFrameStateOuterStateInput = 5;
171 static const int kFrameStateInputCount = kFrameStateOuterStateInput + 1;
172 
173 }  // namespace compiler
174 }  // namespace internal
175 }  // namespace v8
176 
177 #endif  // V8_COMPILER_FRAME_STATES_H_
178