Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/compiler/bytecode-graph-builder.cc

Issue 1570623007: [Interpreter] Add support for CallRuntimeForPair to Bytecode Graph Builder. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_eval
Patch Set: Fix test flags Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/bytecode-graph-builder.h" 5 #include "src/compiler/bytecode-graph-builder.h"
6 6
7 #include "src/compiler/bytecode-branch-analysis.h" 7 #include "src/compiler/bytecode-branch-analysis.h"
8 #include "src/compiler/linkage.h" 8 #include "src/compiler/linkage.h"
9 #include "src/compiler/operator-properties.h" 9 #include "src/compiler/operator-properties.h"
10 #include "src/interpreter/bytecodes.h" 10 #include "src/interpreter/bytecodes.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 namespace compiler { 14 namespace compiler {
15 15
16 // Helper for generating frame states for before and after a bytecode. 16 // Helper for generating frame states for before and after a bytecode.
17 class BytecodeGraphBuilder::FrameStateBeforeAndAfter { 17 class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
18 public: 18 public:
19 FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder, 19 FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder,
20 const interpreter::BytecodeArrayIterator& iterator) 20 const interpreter::BytecodeArrayIterator& iterator)
21 : builder_(builder), id_after_(BailoutId::None()) { 21 : builder_(builder),
22 id_after_(BailoutId::None()),
23 added_to_node_(false),
24 output_poke_offset_(0),
25 output_poke_count_(0) {
22 BailoutId id_before(iterator.current_offset()); 26 BailoutId id_before(iterator.current_offset());
23 frame_state_before_ = builder_->environment()->Checkpoint( 27 frame_state_before_ = builder_->environment()->Checkpoint(
24 id_before, AccumulatorUpdateMode::kOutputIgnored); 28 id_before, OutputFrameStateCombine::Ignore());
25 id_after_ = BailoutId(id_before.ToInt() + iterator.current_bytecode_size()); 29 id_after_ = BailoutId(id_before.ToInt() + iterator.current_bytecode_size());
26 } 30 }
27 31
28 ~FrameStateBeforeAndAfter() { 32 ~FrameStateBeforeAndAfter() {
29 DCHECK(builder_->environment()->StateValuesAreUpToDate( 33 DCHECK(added_to_node_);
30 accumulator_update_mode_)); 34 DCHECK(builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
35 output_poke_count_));
31 } 36 }
32 37
33 private: 38 private:
34 friend class Environment; 39 friend class Environment;
35 40
36 void AddToNode(Node* node, AccumulatorUpdateMode update_mode) { 41 void AddToNode(Node* node, OutputFrameStateCombine combine) {
42 DCHECK(!added_to_node_);
37 int count = OperatorProperties::GetFrameStateInputCount(node->op()); 43 int count = OperatorProperties::GetFrameStateInputCount(node->op());
38 DCHECK_LE(count, 2); 44 DCHECK_LE(count, 2);
39 if (count >= 1) { 45 if (count >= 1) {
40 // Add the frame state for after the operation. 46 // Add the frame state for after the operation.
41 DCHECK_EQ(IrOpcode::kDead, 47 DCHECK_EQ(IrOpcode::kDead,
42 NodeProperties::GetFrameStateInput(node, 0)->opcode()); 48 NodeProperties::GetFrameStateInput(node, 0)->opcode());
43 Node* frame_state_after = 49 Node* frame_state_after =
44 builder_->environment()->Checkpoint(id_after_, update_mode); 50 builder_->environment()->Checkpoint(id_after_, combine);
45 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after); 51 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
46 } 52 }
47 53
48 if (count >= 2) { 54 if (count >= 2) {
49 // Add the frame state for before the operation. 55 // Add the frame state for before the operation.
50 DCHECK_EQ(IrOpcode::kDead, 56 DCHECK_EQ(IrOpcode::kDead,
51 NodeProperties::GetFrameStateInput(node, 1)->opcode()); 57 NodeProperties::GetFrameStateInput(node, 1)->opcode());
52 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_); 58 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
53 } 59 }
54 accumulator_update_mode_ = update_mode; 60
61 if (!combine.IsOutputIgnored()) {
62 output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
63 output_poke_count_ = node->op()->ValueOutputCount();
64 }
65 added_to_node_ = true;
55 } 66 }
56 67
57 BytecodeGraphBuilder* builder_; 68 BytecodeGraphBuilder* builder_;
58 Node* frame_state_before_; 69 Node* frame_state_before_;
59 BailoutId id_after_; 70 BailoutId id_after_;
60 AccumulatorUpdateMode accumulator_update_mode_; 71
72 bool added_to_node_;
73 int output_poke_offset_;
74 int output_poke_count_;
61 }; 75 };
62 76
63 77
64 // Issues: 78 // Issues:
65 // - Scopes - intimately tied to AST. Need to eval what is needed. 79 // - Scopes - intimately tied to AST. Need to eval what is needed.
66 // - Need to resolve closure parameter treatment. 80 // - Need to resolve closure parameter treatment.
67 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, 81 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
68 int register_count, 82 int register_count,
69 int parameter_count, 83 int parameter_count,
70 Node* control_dependency, 84 Node* control_dependency,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( 141 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
128 interpreter::Register the_register) const { 142 interpreter::Register the_register) const {
129 if (the_register.is_parameter()) { 143 if (the_register.is_parameter()) {
130 return the_register.ToParameterIndex(parameter_count()); 144 return the_register.ToParameterIndex(parameter_count());
131 } else { 145 } else {
132 return the_register.index() + register_base(); 146 return the_register.index() + register_base();
133 } 147 }
134 } 148 }
135 149
136 150
137 void BytecodeGraphBuilder::Environment::BindRegister( 151 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
138 interpreter::Register the_register, Node* node) { 152 return values()->at(accumulator_base_);
139 int values_index = RegisterToValuesIndex(the_register);
140 values()->at(values_index) = node;
141 } 153 }
142 154
143 155
144 Node* BytecodeGraphBuilder::Environment::LookupRegister( 156 Node* BytecodeGraphBuilder::Environment::LookupRegister(
145 interpreter::Register the_register) const { 157 interpreter::Register the_register) const {
146 if (the_register.is_function_context()) { 158 if (the_register.is_function_context()) {
147 return builder()->GetFunctionContext(); 159 return builder()->GetFunctionContext();
148 } else if (the_register.is_function_closure()) { 160 } else if (the_register.is_function_closure()) {
149 return builder()->GetFunctionClosure(); 161 return builder()->GetFunctionClosure();
150 } else if (the_register.is_new_target()) { 162 } else if (the_register.is_new_target()) {
151 return builder()->GetNewTarget(); 163 return builder()->GetNewTarget();
152 } else { 164 } else {
153 int values_index = RegisterToValuesIndex(the_register); 165 int values_index = RegisterToValuesIndex(the_register);
154 return values()->at(values_index); 166 return values()->at(values_index);
155 } 167 }
156 } 168 }
157 169
158 170
159 void BytecodeGraphBuilder::Environment::BindAccumulator(
160 Node* node, FrameStateBeforeAndAfter* states) {
161 if (states) {
162 states->AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator);
163 }
164 values()->at(accumulator_base_) = node;
165 }
166
167
168 void BytecodeGraphBuilder::Environment::RecordAfterState(
169 Node* node, FrameStateBeforeAndAfter* states) {
170 states->AddToNode(node, AccumulatorUpdateMode::kOutputIgnored);
171 }
172
173
174 void BytecodeGraphBuilder::Environment::ExchangeRegisters( 171 void BytecodeGraphBuilder::Environment::ExchangeRegisters(
175 interpreter::Register reg0, interpreter::Register reg1) { 172 interpreter::Register reg0, interpreter::Register reg1) {
176 int reg0_index = RegisterToValuesIndex(reg0); 173 int reg0_index = RegisterToValuesIndex(reg0);
177 int reg1_index = RegisterToValuesIndex(reg1); 174 int reg1_index = RegisterToValuesIndex(reg1);
178 Node* saved_reg0_value = values()->at(reg0_index); 175 Node* saved_reg0_value = values()->at(reg0_index);
179 values()->at(reg0_index) = values()->at(reg1_index); 176 values()->at(reg0_index) = values()->at(reg1_index);
180 values()->at(reg1_index) = saved_reg0_value; 177 values()->at(reg1_index) = saved_reg0_value;
181 } 178 }
182 179
183 180
184 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { 181 void BytecodeGraphBuilder::Environment::BindAccumulator(
185 return values()->at(accumulator_base_); 182 Node* node, FrameStateBeforeAndAfter* states) {
183 if (states) {
184 states->AddToNode(node, OutputFrameStateCombine::PokeAt(0));
185 }
186 values()->at(accumulator_base_) = node;
186 } 187 }
187 188
188 189
190 void BytecodeGraphBuilder::Environment::BindRegister(
191 interpreter::Register the_register, Node* node,
192 FrameStateBeforeAndAfter* states) {
193 int values_index = RegisterToValuesIndex(the_register);
194 if (states) {
195 states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
196 values_index));
197 }
198 values()->at(values_index) = node;
199 }
200
201
202 void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
203 interpreter::Register first_reg, Node* node,
204 FrameStateBeforeAndAfter* states) {
205 int values_index = RegisterToValuesIndex(first_reg);
206 if (states) {
207 states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
208 values_index));
209 }
210 for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
211 values()->at(values_index + i) =
212 builder()->NewNode(common()->Projection(i), node);
213 }
214 }
215
216
217 void BytecodeGraphBuilder::Environment::RecordAfterState(
218 Node* node, FrameStateBeforeAndAfter* states) {
219 states->AddToNode(node, OutputFrameStateCombine::Ignore());
220 }
221
222
189 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const { 223 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
190 return GetControlDependency()->opcode() == IrOpcode::kDead; 224 return GetControlDependency()->opcode() == IrOpcode::kDead;
191 } 225 }
192 226
193 227
194 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() { 228 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
195 UpdateControlDependency(builder()->jsgraph()->Dead()); 229 UpdateControlDependency(builder()->jsgraph()->Dead());
196 } 230 }
197 231
198 232
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 int offset, 317 int offset,
284 int count) { 318 int count) {
285 if (StateValuesRequireUpdate(state_values, offset, count)) { 319 if (StateValuesRequireUpdate(state_values, offset, count)) {
286 const Operator* op = common()->StateValues(count); 320 const Operator* op = common()->StateValues(count);
287 (*state_values) = graph()->NewNode(op, count, &values()->at(offset)); 321 (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
288 } 322 }
289 } 323 }
290 324
291 325
292 Node* BytecodeGraphBuilder::Environment::Checkpoint( 326 Node* BytecodeGraphBuilder::Environment::Checkpoint(
293 BailoutId bailout_id, AccumulatorUpdateMode update_mode) { 327 BailoutId bailout_id, OutputFrameStateCombine combine) {
294 if (!builder()->info()->is_deoptimization_enabled()) { 328 if (!builder()->info()->is_deoptimization_enabled()) {
295 return builder()->jsgraph()->EmptyFrameState(); 329 return builder()->jsgraph()->EmptyFrameState();
296 } 330 }
297 331
298 // TODO(rmcilroy): Consider using StateValuesCache for some state values. 332 // TODO(rmcilroy): Consider using StateValuesCache for some state values.
299 UpdateStateValues(&parameters_state_values_, 0, parameter_count()); 333 UpdateStateValues(&parameters_state_values_, 0, parameter_count());
300 UpdateStateValues(&registers_state_values_, register_base(), 334 UpdateStateValues(&registers_state_values_, register_base(),
301 register_count()); 335 register_count());
302 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1); 336 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
303 337
304 OutputFrameStateCombine combine =
305 update_mode == AccumulatorUpdateMode::kOutputIgnored
306 ? OutputFrameStateCombine::Ignore()
307 : OutputFrameStateCombine::PokeAt(0);
308 const Operator* op = common()->FrameState( 338 const Operator* op = common()->FrameState(
309 bailout_id, combine, builder()->frame_state_function_info()); 339 bailout_id, combine, builder()->frame_state_function_info());
310
311 Node* result = graph()->NewNode( 340 Node* result = graph()->NewNode(
312 op, parameters_state_values_, registers_state_values_, 341 op, parameters_state_values_, registers_state_values_,
313 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), 342 accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
314 builder()->graph()->start()); 343 builder()->graph()->start());
315 344
316 return result; 345 return result;
317 } 346 }
318 347
319 348
320 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate( 349 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
321 AccumulatorUpdateMode update_mode) { 350 Node** state_values, int offset, int count, int output_poke_start,
322 return !StateValuesRequireUpdate(&parameters_state_values_, 0, 351 int output_poke_end) {
323 parameter_count()) && 352 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
324 !StateValuesRequireUpdate(&registers_state_values_, register_base(), 353 for (int i = 0; i < count; i++, offset++) {
325 register_count()) && 354 if (offset < output_poke_start || offset >= output_poke_end) {
326 (update_mode == AccumulatorUpdateMode::kOutputInAccumulator || 355 if ((*state_values)->InputAt(i) != values()->at(offset)) {
327 !StateValuesRequireUpdate(&accumulator_state_values_, 356 return false;
328 accumulator_base(), 1)); 357 }
358 }
359 }
360 return true;
329 } 361 }
330 362
331 363
364 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
365 int output_poke_offset, int output_poke_count) {
366 // Poke offset is relative to the top of the stack (i.e., the accumulator).
367 int output_poke_start = accumulator_base() - output_poke_offset;
368 int output_poke_end = output_poke_start + output_poke_count;
369 return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
370 output_poke_start, output_poke_end) &&
371 StateValuesAreUpToDate(&registers_state_values_, register_base(),
372 register_count(), output_poke_start,
373 output_poke_end) &&
374 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
375 1, output_poke_start, output_poke_end);
376 }
377
378
332 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, 379 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
333 CompilationInfo* compilation_info, 380 CompilationInfo* compilation_info,
334 JSGraph* jsgraph) 381 JSGraph* jsgraph)
335 : local_zone_(local_zone), 382 : local_zone_(local_zone),
336 info_(compilation_info), 383 info_(compilation_info),
337 jsgraph_(jsgraph), 384 jsgraph_(jsgraph),
338 bytecode_array_(handle(info()->shared_info()->bytecode_array())), 385 bytecode_array_(handle(info()->shared_info()->bytecode_array())),
339 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( 386 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
340 FrameStateType::kInterpretedFunction, 387 FrameStateType::kInterpretedFunction,
341 bytecode_array()->parameter_count(), 388 bytecode_array()->parameter_count(),
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 Node* vector = BuildLoadImmutableObjectField( 461 Node* vector = BuildLoadImmutableObjectField(
415 shared, SharedFunctionInfo::kFeedbackVectorOffset); 462 shared, SharedFunctionInfo::kFeedbackVectorOffset);
416 feedback_vector_.set(vector); 463 feedback_vector_.set(vector);
417 } 464 }
418 return feedback_vector_.get(); 465 return feedback_vector_.get();
419 } 466 }
420 467
421 468
422 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { 469 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
423 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); 470 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector();
424 FeedbackVectorSlot slot = feedback_vector->ToSlot(slot_id); 471 FeedbackVectorSlot slot;
472 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
473 slot = feedback_vector->ToSlot(slot_id);
474 }
425 return VectorSlotPair(feedback_vector, slot); 475 return VectorSlotPair(feedback_vector, slot);
426 } 476 }
427 477
428 478
429 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) { 479 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) {
430 // Set up the basic structure of the graph. Outputs for {Start} are 480 // Set up the basic structure of the graph. Outputs for {Start} are
431 // the formal parameters (including the receiver) plus context and 481 // the formal parameters (including the receiver) plus context and
432 // closure. 482 // closure.
433 483
434 // Set up the basic structure of the graph. Outputs for {Start} are the formal 484 // Set up the basic structure of the graph. Outputs for {Start} are the formal
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 1244
1195 // Create node to perform the runtime call. 1245 // Create node to perform the runtime call.
1196 const Operator* call = javascript()->CallRuntime(functionId, arg_count); 1246 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1197 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count); 1247 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1198 environment()->BindAccumulator(value, &states); 1248 environment()->BindAccumulator(value, &states);
1199 } 1249 }
1200 1250
1201 1251
1202 void BytecodeGraphBuilder::VisitCallRuntimeForPair( 1252 void BytecodeGraphBuilder::VisitCallRuntimeForPair(
1203 const interpreter::BytecodeArrayIterator& iterator) { 1253 const interpreter::BytecodeArrayIterator& iterator) {
1204 UNIMPLEMENTED(); 1254 FrameStateBeforeAndAfter states(this, iterator);
1255 Runtime::FunctionId functionId =
1256 static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
1257 interpreter::Register first_arg = iterator.GetRegisterOperand(1);
1258 size_t arg_count = iterator.GetCountOperand(2);
1259 interpreter::Register first_return = iterator.GetRegisterOperand(3);
1260
1261 // Create node to perform the runtime call.
1262 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1263 Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1264 environment()->BindRegistersToProjections(first_return, return_pair, &states);
1205 } 1265 }
1206 1266
1207 1267
1208 Node* BytecodeGraphBuilder::ProcessCallNewArguments( 1268 Node* BytecodeGraphBuilder::ProcessCallNewArguments(
1209 const Operator* call_new_op, interpreter::Register callee, 1269 const Operator* call_new_op, interpreter::Register callee,
1210 interpreter::Register first_arg, size_t arity) { 1270 interpreter::Register first_arg, size_t arity) {
1211 Node** all = info()->zone()->NewArray<Node*>(arity); 1271 Node** all = info()->zone()->NewArray<Node*>(arity);
1212 all[0] = environment()->LookupRegister(callee); 1272 all[0] = environment()->LookupRegister(callee);
1213 int first_arg_index = first_arg.index(); 1273 int first_arg_index = first_arg.index();
1214 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) { 1274 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
1943 2003
1944 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 2004 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
1945 if (environment()->IsMarkedAsUnreachable()) return; 2005 if (environment()->IsMarkedAsUnreachable()) return;
1946 environment()->MarkAsUnreachable(); 2006 environment()->MarkAsUnreachable();
1947 exit_controls_.push_back(exit); 2007 exit_controls_.push_back(exit);
1948 } 2008 }
1949 2009
1950 } // namespace compiler 2010 } // namespace compiler
1951 } // namespace internal 2011 } // namespace internal
1952 } // namespace v8 2012 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | test/cctest/compiler/test-run-bytecode-graph-builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698