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

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: 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, int poke_count) {
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 (poke_count) {
62 DCHECK(!combine.IsOutputIgnored());
63 output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
64 output_poke_count_ = poke_count;
65 }
66 added_to_node_ = true;
55 } 67 }
56 68
57 BytecodeGraphBuilder* builder_; 69 BytecodeGraphBuilder* builder_;
58 Node* frame_state_before_; 70 Node* frame_state_before_;
59 BailoutId id_after_; 71 BailoutId id_after_;
60 AccumulatorUpdateMode accumulator_update_mode_; 72
73 bool added_to_node_;
74 int output_poke_offset_;
75 int output_poke_count_;
61 }; 76 };
62 77
63 78
64 // Issues: 79 // Issues:
65 // - Scopes - intimately tied to AST. Need to eval what is needed. 80 // - Scopes - intimately tied to AST. Need to eval what is needed.
66 // - Need to resolve closure parameter treatment. 81 // - Need to resolve closure parameter treatment.
67 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, 82 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
68 int register_count, 83 int register_count,
69 int parameter_count, 84 int parameter_count,
70 Node* control_dependency, 85 Node* control_dependency,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( 142 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
128 interpreter::Register the_register) const { 143 interpreter::Register the_register) const {
129 if (the_register.is_parameter()) { 144 if (the_register.is_parameter()) {
130 return the_register.ToParameterIndex(parameter_count()); 145 return the_register.ToParameterIndex(parameter_count());
131 } else { 146 } else {
132 return the_register.index() + register_base(); 147 return the_register.index() + register_base();
133 } 148 }
134 } 149 }
135 150
136 151
137 void BytecodeGraphBuilder::Environment::BindRegister( 152 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
138 interpreter::Register the_register, Node* node) { 153 return values()->at(accumulator_base_);
139 int values_index = RegisterToValuesIndex(the_register);
140 values()->at(values_index) = node;
141 } 154 }
142 155
143 156
144 Node* BytecodeGraphBuilder::Environment::LookupRegister( 157 Node* BytecodeGraphBuilder::Environment::LookupRegister(
145 interpreter::Register the_register) const { 158 interpreter::Register the_register) const {
146 if (the_register.is_function_context()) { 159 if (the_register.is_function_context()) {
147 return builder()->GetFunctionContext(); 160 return builder()->GetFunctionContext();
148 } else if (the_register.is_function_closure()) { 161 } else if (the_register.is_function_closure()) {
149 return builder()->GetFunctionClosure(); 162 return builder()->GetFunctionClosure();
150 } else if (the_register.is_new_target()) { 163 } else if (the_register.is_new_target()) {
151 return builder()->GetNewTarget(); 164 return builder()->GetNewTarget();
152 } else { 165 } else {
153 int values_index = RegisterToValuesIndex(the_register); 166 int values_index = RegisterToValuesIndex(the_register);
154 return values()->at(values_index); 167 return values()->at(values_index);
155 } 168 }
156 } 169 }
157 170
158 171
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( 172 void BytecodeGraphBuilder::Environment::ExchangeRegisters(
175 interpreter::Register reg0, interpreter::Register reg1) { 173 interpreter::Register reg0, interpreter::Register reg1) {
176 int reg0_index = RegisterToValuesIndex(reg0); 174 int reg0_index = RegisterToValuesIndex(reg0);
177 int reg1_index = RegisterToValuesIndex(reg1); 175 int reg1_index = RegisterToValuesIndex(reg1);
178 Node* saved_reg0_value = values()->at(reg0_index); 176 Node* saved_reg0_value = values()->at(reg0_index);
179 values()->at(reg0_index) = values()->at(reg1_index); 177 values()->at(reg0_index) = values()->at(reg1_index);
180 values()->at(reg1_index) = saved_reg0_value; 178 values()->at(reg1_index) = saved_reg0_value;
181 } 179 }
182 180
183 181
184 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { 182 void BytecodeGraphBuilder::Environment::BindAccumulator(
185 return values()->at(accumulator_base_); 183 Node* node, FrameStateBeforeAndAfter* states) {
184 if (states) {
185 states->AddToNode(node, OutputFrameStateCombine::PokeAt(0), 1);
186 }
187 values()->at(accumulator_base_) = node;
186 } 188 }
187 189
188 190
191 void BytecodeGraphBuilder::Environment::BindRegister(
192 interpreter::Register the_register, Node* node,
193 FrameStateBeforeAndAfter* states) {
194 int values_index = RegisterToValuesIndex(the_register);
195 if (states) {
196 states->AddToNode(
197 node, OutputFrameStateCombine::PokeAt(accumulator_base_ - values_index),
198 1);
199 }
200 values()->at(values_index) = node;
201 }
202
203
204 void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
205 interpreter::Register first_reg, Node* node, int count,
206 FrameStateBeforeAndAfter* states) {
207 int values_index = RegisterToValuesIndex(first_reg);
208 if (states) {
Jarin 2016/01/08 12:32:55 I think you should check that 'node->op()->ValueOu
rmcilroy 2016/01/08 14:47:20 Right, actually I think we should just use node->o
209 states->AddToNode(
210 node, OutputFrameStateCombine::PokeAt(accumulator_base_ - values_index),
211 count);
212 }
213 for (int i = 0; i < count; i++) {
214 values()->at(values_index + i) =
215 builder()->NewNode(common()->Projection(i), node);
216 }
217 }
218
219
220 void BytecodeGraphBuilder::Environment::RecordAfterState(
221 Node* node, FrameStateBeforeAndAfter* states) {
222 states->AddToNode(node, OutputFrameStateCombine::Ignore(), 0);
223 }
224
225
189 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const { 226 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
190 return GetControlDependency()->opcode() == IrOpcode::kDead; 227 return GetControlDependency()->opcode() == IrOpcode::kDead;
191 } 228 }
192 229
193 230
194 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() { 231 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
195 UpdateControlDependency(builder()->jsgraph()->Dead()); 232 UpdateControlDependency(builder()->jsgraph()->Dead());
196 } 233 }
197 234
198 235
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 int offset, 320 int offset,
284 int count) { 321 int count) {
285 if (StateValuesRequireUpdate(state_values, offset, count)) { 322 if (StateValuesRequireUpdate(state_values, offset, count)) {
286 const Operator* op = common()->StateValues(count); 323 const Operator* op = common()->StateValues(count);
287 (*state_values) = graph()->NewNode(op, count, &values()->at(offset)); 324 (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
288 } 325 }
289 } 326 }
290 327
291 328
292 Node* BytecodeGraphBuilder::Environment::Checkpoint( 329 Node* BytecodeGraphBuilder::Environment::Checkpoint(
293 BailoutId bailout_id, AccumulatorUpdateMode update_mode) { 330 BailoutId bailout_id, OutputFrameStateCombine combine) {
294 if (!builder()->info()->is_deoptimization_enabled()) { 331 if (!builder()->info()->is_deoptimization_enabled()) {
295 return builder()->jsgraph()->EmptyFrameState(); 332 return builder()->jsgraph()->EmptyFrameState();
296 } 333 }
297 334
298 // TODO(rmcilroy): Consider using StateValuesCache for some state values. 335 // TODO(rmcilroy): Consider using StateValuesCache for some state values.
299 UpdateStateValues(&parameters_state_values_, 0, parameter_count()); 336 UpdateStateValues(&parameters_state_values_, 0, parameter_count());
300 UpdateStateValues(&registers_state_values_, register_base(), 337 UpdateStateValues(&registers_state_values_, register_base(),
301 register_count()); 338 register_count());
302 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1); 339 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
303 340
304 OutputFrameStateCombine combine =
305 update_mode == AccumulatorUpdateMode::kOutputIgnored
306 ? OutputFrameStateCombine::Ignore()
307 : OutputFrameStateCombine::PokeAt(0);
308 const Operator* op = common()->FrameState( 341 const Operator* op = common()->FrameState(
309 bailout_id, combine, builder()->frame_state_function_info()); 342 bailout_id, combine, builder()->frame_state_function_info());
310
311 Node* result = graph()->NewNode( 343 Node* result = graph()->NewNode(
312 op, parameters_state_values_, registers_state_values_, 344 op, parameters_state_values_, registers_state_values_,
313 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), 345 accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
314 builder()->graph()->start()); 346 builder()->graph()->start());
315 347
316 return result; 348 return result;
317 } 349 }
318 350
319 351
320 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate( 352 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
321 AccumulatorUpdateMode update_mode) { 353 Node** state_values, int offset, int count, int output_poke_start,
322 return !StateValuesRequireUpdate(&parameters_state_values_, 0, 354 int output_poke_end) {
323 parameter_count()) && 355 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
324 !StateValuesRequireUpdate(&registers_state_values_, register_base(), 356 for (int i = 0; i < count; i++, offset++) {
325 register_count()) && 357 if (offset < output_poke_start || offset >= output_poke_end) {
326 (update_mode == AccumulatorUpdateMode::kOutputInAccumulator || 358 if ((*state_values)->InputAt(i) != values()->at(offset)) {
327 !StateValuesRequireUpdate(&accumulator_state_values_, 359 return false;
328 accumulator_base(), 1)); 360 }
361 }
362 }
363 return true;
329 } 364 }
330 365
331 366
367 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
368 int output_poke_offset, int output_poke_count) {
369 // Poke offset is relative to the top of the stack (i.e., the accumulator).
370 int output_poke_start = accumulator_base() - output_poke_offset;
371 int output_poke_end = output_poke_start + output_poke_count;
372 return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
373 output_poke_start, output_poke_end) &&
374 StateValuesAreUpToDate(&registers_state_values_, register_base(),
375 register_count(), output_poke_start,
376 output_poke_end) &&
377 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
378 1, output_poke_start, output_poke_end);
379 }
380
381
332 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, 382 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
333 CompilationInfo* compilation_info, 383 CompilationInfo* compilation_info,
334 JSGraph* jsgraph) 384 JSGraph* jsgraph)
335 : local_zone_(local_zone), 385 : local_zone_(local_zone),
336 info_(compilation_info), 386 info_(compilation_info),
337 jsgraph_(jsgraph), 387 jsgraph_(jsgraph),
338 bytecode_array_(handle(info()->shared_info()->bytecode_array())), 388 bytecode_array_(handle(info()->shared_info()->bytecode_array())),
339 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( 389 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
340 FrameStateType::kInterpretedFunction, 390 FrameStateType::kInterpretedFunction,
341 bytecode_array()->parameter_count(), 391 bytecode_array()->parameter_count(),
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 Node* vector = BuildLoadImmutableObjectField( 464 Node* vector = BuildLoadImmutableObjectField(
415 shared, SharedFunctionInfo::kFeedbackVectorOffset); 465 shared, SharedFunctionInfo::kFeedbackVectorOffset);
416 feedback_vector_.set(vector); 466 feedback_vector_.set(vector);
417 } 467 }
418 return feedback_vector_.get(); 468 return feedback_vector_.get();
419 } 469 }
420 470
421 471
422 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { 472 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
423 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); 473 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector();
424 FeedbackVectorSlot slot = feedback_vector->ToSlot(slot_id); 474 FeedbackVectorSlot slot;
475 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
476 slot = feedback_vector->ToSlot(slot_id);
477 }
425 return VectorSlotPair(feedback_vector, slot); 478 return VectorSlotPair(feedback_vector, slot);
426 } 479 }
427 480
428 481
429 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) { 482 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) {
430 // Set up the basic structure of the graph. Outputs for {Start} are 483 // Set up the basic structure of the graph. Outputs for {Start} are
431 // the formal parameters (including the receiver) plus context and 484 // the formal parameters (including the receiver) plus context and
432 // closure. 485 // closure.
433 486
434 // Set up the basic structure of the graph. Outputs for {Start} are the formal 487 // 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 1247
1195 // Create node to perform the runtime call. 1248 // Create node to perform the runtime call.
1196 const Operator* call = javascript()->CallRuntime(functionId, arg_count); 1249 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1197 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count); 1250 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1198 environment()->BindAccumulator(value, &states); 1251 environment()->BindAccumulator(value, &states);
1199 } 1252 }
1200 1253
1201 1254
1202 void BytecodeGraphBuilder::VisitCallRuntimeForPair( 1255 void BytecodeGraphBuilder::VisitCallRuntimeForPair(
1203 const interpreter::BytecodeArrayIterator& iterator) { 1256 const interpreter::BytecodeArrayIterator& iterator) {
1204 UNIMPLEMENTED(); 1257 FrameStateBeforeAndAfter states(this, iterator);
1258 Runtime::FunctionId functionId =
1259 static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
1260 interpreter::Register first_arg = iterator.GetRegisterOperand(1);
1261 size_t arg_count = iterator.GetCountOperand(2);
1262 interpreter::Register first_return = iterator.GetRegisterOperand(3);
1263
1264 // Create node to perform the runtime call.
1265 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1266 Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1267 environment()->BindRegistersToProjections(first_return, return_pair, 2,
1268 &states);
1205 } 1269 }
1206 1270
1207 1271
1208 Node* BytecodeGraphBuilder::ProcessCallNewArguments( 1272 Node* BytecodeGraphBuilder::ProcessCallNewArguments(
1209 const Operator* call_new_op, interpreter::Register callee, 1273 const Operator* call_new_op, interpreter::Register callee,
1210 interpreter::Register first_arg, size_t arity) { 1274 interpreter::Register first_arg, size_t arity) {
1211 Node** all = info()->zone()->NewArray<Node*>(arity); 1275 Node** all = info()->zone()->NewArray<Node*>(arity);
1212 all[0] = environment()->LookupRegister(callee); 1276 all[0] = environment()->LookupRegister(callee);
1213 int first_arg_index = first_arg.index(); 1277 int first_arg_index = first_arg.index();
1214 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) { 1278 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
1943 2007
1944 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 2008 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
1945 if (environment()->IsMarkedAsUnreachable()) return; 2009 if (environment()->IsMarkedAsUnreachable()) return;
1946 environment()->MarkAsUnreachable(); 2010 environment()->MarkAsUnreachable();
1947 exit_controls_.push_back(exit); 2011 exit_controls_.push_back(exit);
1948 } 2012 }
1949 2013
1950 } // namespace compiler 2014 } // namespace compiler
1951 } // namespace internal 2015 } // namespace internal
1952 } // namespace v8 2016 } // 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