Line data Source code
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 : #include "src/compiler/frame-states.h"
6 :
7 : #include "src/base/functional.h"
8 : #include "src/callable.h"
9 : #include "src/compiler/graph.h"
10 : #include "src/compiler/js-graph.h"
11 : #include "src/compiler/node.h"
12 : #include "src/handles-inl.h"
13 : #include "src/objects-inl.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 : namespace compiler {
18 :
19 0 : size_t hash_value(OutputFrameStateCombine const& sc) {
20 29743535 : return base::hash_value(sc.parameter_);
21 : }
22 :
23 :
24 77 : std::ostream& operator<<(std::ostream& os, OutputFrameStateCombine const& sc) {
25 77 : if (sc.parameter_ == OutputFrameStateCombine::kInvalidIndex)
26 77 : return os << "Ignore";
27 0 : return os << "PokeAt(" << sc.parameter_ << ")";
28 : }
29 :
30 :
31 9085195 : bool operator==(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
32 9005227 : return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() &&
33 9749072 : lhs.state_combine() == rhs.state_combine() &&
34 9085195 : lhs.function_info() == rhs.function_info();
35 : }
36 :
37 :
38 0 : bool operator!=(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
39 0 : return !(lhs == rhs);
40 : }
41 :
42 :
43 29743792 : size_t hash_value(FrameStateInfo const& info) {
44 59487053 : return base::hash_combine(static_cast<int>(info.type()), info.bailout_id(),
45 29743261 : info.state_combine());
46 : }
47 :
48 :
49 77 : std::ostream& operator<<(std::ostream& os, FrameStateType type) {
50 77 : switch (type) {
51 : case FrameStateType::kInterpretedFunction:
52 77 : os << "INTERPRETED_FRAME";
53 77 : break;
54 : case FrameStateType::kArgumentsAdaptor:
55 0 : os << "ARGUMENTS_ADAPTOR";
56 0 : break;
57 : case FrameStateType::kConstructStub:
58 0 : os << "CONSTRUCT_STUB";
59 0 : break;
60 : case FrameStateType::kBuiltinContinuation:
61 0 : os << "BUILTIN_CONTINUATION_FRAME";
62 0 : break;
63 : case FrameStateType::kJavaScriptBuiltinContinuation:
64 0 : os << "JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME";
65 0 : break;
66 : case FrameStateType::kJavaScriptBuiltinContinuationWithCatch:
67 0 : os << "JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME";
68 0 : break;
69 : }
70 77 : return os;
71 : }
72 :
73 :
74 77 : std::ostream& operator<<(std::ostream& os, FrameStateInfo const& info) {
75 154 : os << info.type() << ", " << info.bailout_id() << ", "
76 154 : << info.state_combine();
77 : Handle<SharedFunctionInfo> shared_info;
78 77 : if (info.shared_info().ToHandle(&shared_info)) {
79 154 : os << ", " << Brief(*shared_info);
80 : }
81 77 : return os;
82 : }
83 :
84 : namespace {
85 :
86 : // Lazy deopt points where the frame state is assocated with a call get an
87 : // additional parameter for the return result from the call. The return result
88 : // is added by the deoptimizer and not explicitly specified in the frame state.
89 : // Lazy deopt points which can catch exceptions further get an additional
90 : // parameter, namely the exception thrown. The exception is also added by the
91 : // deoptimizer.
92 3075 : uint8_t DeoptimizerParameterCountFor(ContinuationFrameStateMode mode) {
93 3075 : switch (mode) {
94 : case ContinuationFrameStateMode::EAGER:
95 : return 0;
96 : case ContinuationFrameStateMode::LAZY:
97 3075 : return 1;
98 : case ContinuationFrameStateMode::LAZY_WITH_CATCH:
99 0 : return 2;
100 : }
101 0 : UNREACHABLE();
102 : }
103 :
104 9588 : Node* CreateBuiltinContinuationFrameStateCommon(
105 : JSGraph* jsgraph, FrameStateType frame_type, Builtins::Name name,
106 : Node* closure, Node* context, Node** parameters, int parameter_count,
107 : Node* outer_frame_state,
108 : Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>()) {
109 : Isolate* const isolate = jsgraph->isolate();
110 : Graph* const graph = jsgraph->graph();
111 : CommonOperatorBuilder* const common = jsgraph->common();
112 :
113 9588 : BailoutId bailout_id = Builtins::GetContinuationBailoutId(name);
114 9588 : Callable callable = Builtins::CallableFor(isolate, name);
115 :
116 : const Operator* op_param =
117 9588 : common->StateValues(parameter_count, SparseInputMask::Dense());
118 9588 : Node* params_node = graph->NewNode(op_param, parameter_count, parameters);
119 :
120 : const FrameStateFunctionInfo* state_info =
121 : common->CreateFrameStateFunctionInfo(frame_type, parameter_count, 0,
122 9588 : shared);
123 : const Operator* op = common->FrameState(
124 9588 : bailout_id, OutputFrameStateCombine::Ignore(), state_info);
125 :
126 9588 : Node* frame_state = graph->NewNode(
127 : op, params_node, jsgraph->EmptyStateValues(), jsgraph->EmptyStateValues(),
128 : context, closure, outer_frame_state);
129 :
130 9588 : return frame_state;
131 : }
132 :
133 : } // namespace
134 :
135 3075 : Node* CreateStubBuiltinContinuationFrameState(
136 : JSGraph* jsgraph, Builtins::Name name, Node* context,
137 : Node* const* parameters, int parameter_count, Node* outer_frame_state,
138 : ContinuationFrameStateMode mode) {
139 : Isolate* isolate = jsgraph->isolate();
140 3075 : Callable callable = Builtins::CallableFor(isolate, name);
141 : CallInterfaceDescriptor descriptor = callable.descriptor();
142 :
143 : std::vector<Node*> actual_parameters;
144 : // Stack parameters first. Depending on {mode}, final parameters are added
145 : // by the deoptimizer and aren't explicitly passed in the frame state.
146 : int stack_parameter_count =
147 3075 : descriptor.GetParameterCount() - DeoptimizerParameterCountFor(mode);
148 : // Reserving space in the vector, except for the case where
149 : // stack_parameter_count is -1.
150 6150 : actual_parameters.reserve(stack_parameter_count >= 0
151 3075 : ? stack_parameter_count +
152 : descriptor.GetRegisterParameterCount()
153 3075 : : 0);
154 7271 : for (int i = 0; i < stack_parameter_count; ++i) {
155 2098 : actual_parameters.push_back(
156 4196 : parameters[descriptor.GetRegisterParameterCount() + i]);
157 : }
158 : // Register parameters follow, context will be added by instruction selector
159 : // during FrameState translation.
160 3075 : for (int i = 0; i < descriptor.GetRegisterParameterCount(); ++i) {
161 0 : actual_parameters.push_back(parameters[i]);
162 : }
163 :
164 6150 : return CreateBuiltinContinuationFrameStateCommon(
165 : jsgraph, FrameStateType::kBuiltinContinuation, name,
166 : jsgraph->UndefinedConstant(), context, actual_parameters.data(),
167 6150 : static_cast<int>(actual_parameters.size()), outer_frame_state);
168 : }
169 :
170 6513 : Node* CreateJavaScriptBuiltinContinuationFrameState(
171 : JSGraph* jsgraph, const SharedFunctionInfoRef& shared, Builtins::Name name,
172 : Node* target, Node* context, Node* const* stack_parameters,
173 : int stack_parameter_count, Node* outer_frame_state,
174 : ContinuationFrameStateMode mode) {
175 : Isolate* const isolate = jsgraph->isolate();
176 6513 : Callable const callable = Builtins::CallableFor(isolate, name);
177 :
178 : // Depending on {mode}, final parameters are added by the deoptimizer
179 : // and aren't explicitly passed in the frame state.
180 : DCHECK_EQ(Builtins::GetStackParameterCount(name) + 1, // add receiver
181 : stack_parameter_count + DeoptimizerParameterCountFor(mode));
182 :
183 6513 : Node* argc = jsgraph->Constant(Builtins::GetStackParameterCount(name));
184 :
185 : // Stack parameters first. They must be first because the receiver is expected
186 : // to be the second value in the translation when creating stack crawls
187 : // (e.g. Error.stack) of optimized JavaScript frames.
188 : std::vector<Node*> actual_parameters;
189 65959 : for (int i = 0; i < stack_parameter_count; ++i) {
190 29723 : actual_parameters.push_back(stack_parameters[i]);
191 : }
192 :
193 : // Register parameters follow stack paraemters. The context will be added by
194 : // instruction selector during FrameState translation.
195 6513 : actual_parameters.push_back(target);
196 13026 : actual_parameters.push_back(jsgraph->UndefinedConstant());
197 6513 : actual_parameters.push_back(argc);
198 :
199 13026 : return CreateBuiltinContinuationFrameStateCommon(
200 : jsgraph,
201 : mode == ContinuationFrameStateMode::LAZY_WITH_CATCH
202 : ? FrameStateType::kJavaScriptBuiltinContinuationWithCatch
203 : : FrameStateType::kJavaScriptBuiltinContinuation,
204 : name, target, context, &actual_parameters[0],
205 : static_cast<int>(actual_parameters.size()), outer_frame_state,
206 13026 : shared.object());
207 : }
208 :
209 : } // namespace compiler
210 : } // namespace internal
211 122004 : } // namespace v8
|