Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/linkage.h" | 7 #include "src/compiler/linkage.h" |
| 8 #include "src/compiler/operator-properties.h" | 8 #include "src/compiler/operator-properties.h" |
| 9 #include "src/interpreter/bytecode-array-iterator.h" | 9 #include "src/interpreter/bytecode-array-iterator.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 // Issues: | 16 // Issues: |
| 17 // - Need to deal with FrameState / FrameStateBeforeAndAfter / StateValue. | |
| 18 // - Scopes - intimately tied to AST. Need to eval what is needed. | 17 // - Scopes - intimately tied to AST. Need to eval what is needed. |
| 19 // - Need to resolve closure parameter treatment. | 18 // - Need to resolve closure parameter treatment. |
| 20 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, | 19 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, |
| 21 int register_count, | 20 int register_count, |
| 22 int parameter_count, | 21 int parameter_count, |
| 23 Node* control_dependency, | 22 Node* control_dependency, |
| 24 Node* context) | 23 Node* context) |
| 25 : builder_(builder), | 24 : builder_(builder), |
| 26 register_count_(register_count), | 25 register_count_(register_count), |
| 27 parameter_count_(parameter_count), | 26 parameter_count_(parameter_count), |
| 28 context_(context), | 27 context_(context), |
| 29 control_dependency_(control_dependency), | 28 control_dependency_(control_dependency), |
| 30 effect_dependency_(control_dependency), | 29 effect_dependency_(control_dependency), |
| 31 values_(builder->local_zone()) { | 30 values_(builder->local_zone()), |
| 31 parameters_state_values_(nullptr), | |
| 32 registers_state_values_(nullptr), | |
| 33 accumulator_state_values_(nullptr) { | |
| 32 // The layout of values_ is: | 34 // The layout of values_ is: |
| 33 // | 35 // |
| 34 // [receiver] [parameters] [registers] | 36 // [receiver] [parameters] [registers] [accumulator] |
| 35 // | 37 // |
| 36 // parameter[0] is the receiver (this), parameters 1..N are the | 38 // parameter[0] is the receiver (this), parameters 1..N are the |
| 37 // parameters supplied to the method (arg0..argN-1). The accumulator | 39 // parameters supplied to the method (arg0..argN-1). The accumulator |
| 38 // is stored separately. | 40 // is stored separately. |
| 39 | 41 |
| 40 // Parameters including the receiver | 42 // Parameters including the receiver |
| 41 for (int i = 0; i < parameter_count; i++) { | 43 for (int i = 0; i < parameter_count; i++) { |
| 42 const char* debug_name = (i == 0) ? "%this" : nullptr; | 44 const char* debug_name = (i == 0) ? "%this" : nullptr; |
| 43 const Operator* op = common()->Parameter(i, debug_name); | 45 const Operator* op = common()->Parameter(i, debug_name); |
| 44 Node* parameter = builder->graph()->NewNode(op, graph()->start()); | 46 Node* parameter = builder->graph()->NewNode(op, graph()->start()); |
| 45 values()->push_back(parameter); | 47 values()->push_back(parameter); |
| 46 } | 48 } |
| 47 | 49 |
| 48 // Registers | 50 // Registers |
| 49 register_base_ = static_cast<int>(values()->size()); | 51 register_base_ = static_cast<int>(values()->size()); |
| 50 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); | 52 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); |
| 51 values()->insert(values()->end(), register_count, undefined_constant); | 53 values()->insert(values()->end(), register_count, undefined_constant); |
| 52 | 54 |
| 53 // Accumulator | 55 // Accumulator |
| 54 accumulator_ = undefined_constant; | 56 accumulator_base_ = static_cast<int>(values()->size()); |
| 57 values()->push_back(undefined_constant); | |
| 55 } | 58 } |
| 56 | 59 |
| 57 | 60 |
| 58 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( | 61 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( |
| 59 interpreter::Register the_register) const { | 62 interpreter::Register the_register) const { |
| 60 if (the_register.is_parameter()) { | 63 if (the_register.is_parameter()) { |
| 61 return the_register.ToParameterIndex(parameter_count()); | 64 return the_register.ToParameterIndex(parameter_count()); |
| 62 } else { | 65 } else { |
| 63 return the_register.index() + register_base(); | 66 return the_register.index() + register_base(); |
| 64 } | 67 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 81 } else if (the_register.is_new_target()) { | 84 } else if (the_register.is_new_target()) { |
| 82 return builder()->GetNewTarget(); | 85 return builder()->GetNewTarget(); |
| 83 } else { | 86 } else { |
| 84 int values_index = RegisterToValuesIndex(the_register); | 87 int values_index = RegisterToValuesIndex(the_register); |
| 85 return values()->at(values_index); | 88 return values()->at(values_index); |
| 86 } | 89 } |
| 87 } | 90 } |
| 88 | 91 |
| 89 | 92 |
| 90 void BytecodeGraphBuilder::Environment::BindAccumulator(Node* node) { | 93 void BytecodeGraphBuilder::Environment::BindAccumulator(Node* node) { |
| 91 accumulator_ = node; | 94 values()->at(accumulator_base_) = node; |
| 92 } | 95 } |
| 93 | 96 |
| 94 | 97 |
| 95 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { | 98 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { |
| 96 return accumulator_; | 99 return values()->at(accumulator_base_); |
| 97 } | 100 } |
| 98 | 101 |
| 99 | 102 |
| 100 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const { | 103 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const { |
| 101 return GetControlDependency()->opcode() == IrOpcode::kDead; | 104 return GetControlDependency()->opcode() == IrOpcode::kDead; |
| 102 } | 105 } |
| 103 | 106 |
| 104 | 107 |
| 105 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() { | 108 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() { |
| 106 UpdateControlDependency(builder()->jsgraph()->Dead()); | 109 UpdateControlDependency(builder()->jsgraph()->Dead()); |
| 107 } | 110 } |
| 108 | 111 |
| 109 | 112 |
| 113 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, | |
| 114 int offset, | |
| 115 int count) { | |
| 116 bool should_update = false; | |
| 117 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | |
| 118 if (*state_values == NULL) { | |
| 119 should_update = true; | |
| 120 } else { | |
| 121 DCHECK_EQ((*state_values)->InputCount(), count); | |
| 122 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); | |
| 123 for (int i = 0; i < count; i++) { | |
| 124 if ((*state_values)->InputAt(i) != env_values[i]) { | |
| 125 should_update = true; | |
| 126 break; | |
| 127 } | |
| 128 } | |
| 129 } | |
| 130 if (should_update) { | |
| 131 const Operator* op = common()->StateValues(count); | |
| 132 (*state_values) = graph()->NewNode(op, count, env_values); | |
| 133 } | |
| 134 } | |
| 135 | |
| 136 | |
| 137 Node* BytecodeGraphBuilder::Environment::Checkpoint( | |
| 138 BailoutId bailout_id, AccumulatorUpdateMode update_mode) { | |
| 139 if (!builder()->info()->is_deoptimization_enabled()) { | |
| 140 return builder()->jsgraph()->EmptyFrameState(); | |
| 141 } | |
| 142 | |
| 143 // TODO(rmcilroy): Consider using StateValuesCache for some state values. | |
| 144 UpdateStateValues(¶meters_state_values_, 0, parameter_count()); | |
| 145 UpdateStateValues(®isters_state_values_, register_base(), | |
| 146 register_count()); | |
| 147 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1); | |
| 148 | |
| 149 OutputFrameStateCombine combine = | |
| 150 update_mode == AccumulatorUpdateMode::kOutputIgnored | |
|
Jarin
2015/12/13 20:26:30
I do not understand why you differentiate between
rmcilroy
2015/12/16 15:40:56
We need this because some bytecodes don't modify t
Jarin
2015/12/17 09:44:05
Acknowledged.
| |
| 151 ? OutputFrameStateCombine::Ignore() | |
| 152 : OutputFrameStateCombine::Push(); | |
| 153 const Operator* op = common()->FrameState( | |
| 154 bailout_id, combine, builder()->frame_state_function_info()); | |
| 155 | |
| 156 Node* result = graph()->NewNode( | |
| 157 op, parameters_state_values_, registers_state_values_, | |
| 158 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), | |
| 159 builder()->graph()->start()); | |
| 160 | |
| 161 return result; | |
| 162 } | |
| 163 | |
| 164 | |
| 165 // Helper for generating frame states for before and after a bytecode. | |
| 166 class BytecodeGraphBuilder::FrameStateBeforeAndAfter { | |
| 167 public: | |
| 168 FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder, | |
| 169 const interpreter::BytecodeArrayIterator& iterator) | |
| 170 : builder_(builder), id_after_(BailoutId::None()) { | |
| 171 BailoutId id_before(iterator.current_offset()); | |
| 172 frame_state_before_ = builder_->environment()->Checkpoint( | |
| 173 id_before, AccumulatorUpdateMode::kOutputIgnored); | |
| 174 id_after_ = BailoutId(id_before.ToInt() + iterator.current_bytecode_size()); | |
| 175 } | |
| 176 | |
| 177 void AddToNode(Node* node, AccumulatorUpdateMode update_mode) { | |
| 178 int count = OperatorProperties::GetFrameStateInputCount(node->op()); | |
| 179 DCHECK_LE(count, 2); | |
| 180 | |
| 181 if (count >= 1) { | |
| 182 // Add the frame state for after the operation. | |
| 183 DCHECK_EQ(IrOpcode::kDead, | |
| 184 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | |
| 185 Node* frame_state_after = | |
| 186 builder_->environment()->Checkpoint(id_after_, update_mode); | |
| 187 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after); | |
| 188 } | |
| 189 | |
| 190 if (count >= 2) { | |
| 191 // Add the frame state for before the operation. | |
| 192 DCHECK_EQ(IrOpcode::kDead, | |
| 193 NodeProperties::GetFrameStateInput(node, 1)->opcode()); | |
| 194 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_); | |
| 195 } | |
| 196 } | |
| 197 | |
| 198 private: | |
| 199 BytecodeGraphBuilder* builder_; | |
| 200 Node* frame_state_before_; | |
| 201 BailoutId id_after_; | |
| 202 }; | |
| 203 | |
| 204 | |
| 110 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, | 205 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, |
| 111 CompilationInfo* compilation_info, | 206 CompilationInfo* compilation_info, |
| 112 JSGraph* jsgraph) | 207 JSGraph* jsgraph) |
| 113 : local_zone_(local_zone), | 208 : local_zone_(local_zone), |
| 114 info_(compilation_info), | 209 info_(compilation_info), |
| 115 jsgraph_(jsgraph), | 210 jsgraph_(jsgraph), |
| 211 bytecode_array_(handle(info()->shared_info()->bytecode_array())), | |
| 212 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | |
| 213 FrameStateType::kInterpretedFunction, | |
| 214 bytecode_array()->parameter_count(), | |
| 215 bytecode_array()->register_count(), info()->shared_info(), | |
| 216 CALL_MAINTAINS_NATIVE_CONTEXT)), | |
| 116 input_buffer_size_(0), | 217 input_buffer_size_(0), |
| 117 input_buffer_(nullptr), | 218 input_buffer_(nullptr), |
| 118 exit_controls_(local_zone) { | 219 exit_controls_(local_zone) {} |
| 119 bytecode_array_ = handle(info()->shared_info()->bytecode_array()); | |
| 120 } | |
| 121 | 220 |
| 122 | 221 |
| 123 Node* BytecodeGraphBuilder::GetNewTarget() { | 222 Node* BytecodeGraphBuilder::GetNewTarget() { |
| 124 if (!new_target_.is_set()) { | 223 if (!new_target_.is_set()) { |
| 125 int params = bytecode_array()->parameter_count(); | 224 int params = bytecode_array()->parameter_count(); |
| 126 int index = Linkage::GetJSCallNewTargetParamIndex(params); | 225 int index = Linkage::GetJSCallNewTargetParamIndex(params); |
| 127 const Operator* op = common()->Parameter(index, "%new.target"); | 226 const Operator* op = common()->Parameter(index, "%new.target"); |
| 128 Node* node = NewNode(op, graph()->start()); | 227 Node* node = NewNode(op, graph()->start()); |
| 129 new_target_.set(node); | 228 new_target_.set(node); |
| 130 } | 229 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 } | 290 } |
| 192 | 291 |
| 193 | 292 |
| 194 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { | 293 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { |
| 195 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); | 294 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); |
| 196 FeedbackVectorSlot slot = feedback_vector->ToSlot(slot_id); | 295 FeedbackVectorSlot slot = feedback_vector->ToSlot(slot_id); |
| 197 return VectorSlotPair(feedback_vector, slot); | 296 return VectorSlotPair(feedback_vector, slot); |
| 198 } | 297 } |
| 199 | 298 |
| 200 | 299 |
| 201 // TODO(mythria): Replace this function with one which adds real frame state. | |
| 202 // Also add before and after frame states and checkpointing if required. | |
| 203 void BytecodeGraphBuilder::AddEmptyFrameStateInputs(Node* node) { | |
| 204 int frame_state_count = | |
| 205 OperatorProperties::GetFrameStateInputCount(node->op()); | |
| 206 for (int i = 0; i < frame_state_count; i++) { | |
| 207 NodeProperties::ReplaceFrameStateInput(node, i, | |
| 208 jsgraph()->EmptyFrameState()); | |
| 209 } | |
| 210 } | |
| 211 | |
| 212 | |
| 213 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) { | 300 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) { |
| 214 // Set up the basic structure of the graph. Outputs for {Start} are | 301 // Set up the basic structure of the graph. Outputs for {Start} are |
| 215 // the formal parameters (including the receiver) plus context and | 302 // the formal parameters (including the receiver) plus context and |
| 216 // closure. | 303 // closure. |
| 217 | 304 |
| 218 // Set up the basic structure of the graph. Outputs for {Start} are the formal | 305 // Set up the basic structure of the graph. Outputs for {Start} are the formal |
| 219 // parameters (including the receiver) plus new target, number of arguments, | 306 // parameters (including the receiver) plus new target, number of arguments, |
| 220 // context and closure. | 307 // context and closure. |
| 221 int actual_parameter_count = bytecode_array()->parameter_count() + 4; | 308 int actual_parameter_count = bytecode_array()->parameter_count() + 4; |
| 222 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); | 309 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 void BytecodeGraphBuilder::VisitMov( | 429 void BytecodeGraphBuilder::VisitMov( |
| 343 const interpreter::BytecodeArrayIterator& iterator) { | 430 const interpreter::BytecodeArrayIterator& iterator) { |
| 344 Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 431 Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 345 environment()->BindRegister(iterator.GetRegisterOperand(1), value); | 432 environment()->BindRegister(iterator.GetRegisterOperand(1), value); |
| 346 } | 433 } |
| 347 | 434 |
| 348 | 435 |
| 349 void BytecodeGraphBuilder::BuildLoadGlobal( | 436 void BytecodeGraphBuilder::BuildLoadGlobal( |
| 350 const interpreter::BytecodeArrayIterator& iterator, | 437 const interpreter::BytecodeArrayIterator& iterator, |
| 351 TypeofMode typeof_mode) { | 438 TypeofMode typeof_mode) { |
| 439 FrameStateBeforeAndAfter states(this, iterator); | |
| 352 Handle<Name> name = | 440 Handle<Name> name = |
| 353 Handle<Name>::cast(iterator.GetConstantForIndexOperand(0)); | 441 Handle<Name>::cast(iterator.GetConstantForIndexOperand(0)); |
| 354 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); | 442 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); |
| 355 | 443 |
| 356 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode); | 444 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode); |
| 357 Node* node = NewNode(op, BuildLoadFeedbackVector()); | 445 Node* node = NewNode(op, BuildLoadFeedbackVector()); |
| 358 AddEmptyFrameStateInputs(node); | 446 states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
| 359 environment()->BindAccumulator(node); | 447 environment()->BindAccumulator(node); |
| 360 } | 448 } |
| 361 | 449 |
| 362 | 450 |
| 363 void BytecodeGraphBuilder::VisitLdaGlobalSloppy( | 451 void BytecodeGraphBuilder::VisitLdaGlobalSloppy( |
| 364 const interpreter::BytecodeArrayIterator& iterator) { | 452 const interpreter::BytecodeArrayIterator& iterator) { |
| 365 DCHECK(is_sloppy(language_mode())); | 453 DCHECK(is_sloppy(language_mode())); |
| 366 BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF); | 454 BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF); |
| 367 } | 455 } |
| 368 | 456 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 | 499 |
| 412 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrictWide( | 500 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrictWide( |
| 413 const interpreter::BytecodeArrayIterator& iterator) { | 501 const interpreter::BytecodeArrayIterator& iterator) { |
| 414 DCHECK(is_strict(language_mode())); | 502 DCHECK(is_strict(language_mode())); |
| 415 BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF); | 503 BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF); |
| 416 } | 504 } |
| 417 | 505 |
| 418 | 506 |
| 419 void BytecodeGraphBuilder::BuildStoreGlobal( | 507 void BytecodeGraphBuilder::BuildStoreGlobal( |
| 420 const interpreter::BytecodeArrayIterator& iterator) { | 508 const interpreter::BytecodeArrayIterator& iterator) { |
| 509 FrameStateBeforeAndAfter states(this, iterator); | |
|
Jarin
2015/12/13 20:26:30
Could we please implement the minimal machinery ne
rmcilroy
2015/12/16 15:40:56
As discussed offline, keeping this machinary in si
Jarin
2015/12/17 09:44:05
Ack. Even though I am wondering whether the FrameS
rmcilroy
2015/12/17 14:43:48
Good point on the fact that the OutputIgnore/Outpu
| |
| 421 Handle<Name> name = | 510 Handle<Name> name = |
| 422 Handle<Name>::cast(iterator.GetConstantForIndexOperand(0)); | 511 Handle<Name>::cast(iterator.GetConstantForIndexOperand(0)); |
| 423 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); | 512 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); |
| 424 Node* value = environment()->LookupAccumulator(); | 513 Node* value = environment()->LookupAccumulator(); |
| 425 | 514 |
| 426 const Operator* op = | 515 const Operator* op = |
| 427 javascript()->StoreGlobal(language_mode(), name, feedback); | 516 javascript()->StoreGlobal(language_mode(), name, feedback); |
| 428 Node* node = NewNode(op, value, BuildLoadFeedbackVector()); | 517 Node* node = NewNode(op, value, BuildLoadFeedbackVector()); |
| 429 AddEmptyFrameStateInputs(node); | 518 states.AddToNode(node, AccumulatorUpdateMode::kOutputIgnored); |
| 430 } | 519 } |
| 431 | 520 |
| 432 | 521 |
| 433 void BytecodeGraphBuilder::VisitStaGlobalSloppy( | 522 void BytecodeGraphBuilder::VisitStaGlobalSloppy( |
| 434 const interpreter::BytecodeArrayIterator& iterator) { | 523 const interpreter::BytecodeArrayIterator& iterator) { |
| 435 DCHECK(is_sloppy(language_mode())); | 524 DCHECK(is_sloppy(language_mode())); |
| 436 BuildStoreGlobal(iterator); | 525 BuildStoreGlobal(iterator); |
| 437 } | 526 } |
| 438 | 527 |
| 439 | 528 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 | 564 |
| 476 void BytecodeGraphBuilder::VisitStaContextSlot( | 565 void BytecodeGraphBuilder::VisitStaContextSlot( |
| 477 const interpreter::BytecodeArrayIterator& iterator) { | 566 const interpreter::BytecodeArrayIterator& iterator) { |
| 478 // TODO(mythria): LoadContextSlots are unrolled by the required depth when | 567 // TODO(mythria): LoadContextSlots are unrolled by the required depth when |
| 479 // generating bytecode. Hence the value of depth is always 0. Update this | 568 // generating bytecode. Hence the value of depth is always 0. Update this |
| 480 // code, when the implementation changes. | 569 // code, when the implementation changes. |
| 481 const Operator* op = | 570 const Operator* op = |
| 482 javascript()->StoreContext(0, iterator.GetIndexOperand(1)); | 571 javascript()->StoreContext(0, iterator.GetIndexOperand(1)); |
| 483 Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 572 Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 484 Node* value = environment()->LookupAccumulator(); | 573 Node* value = environment()->LookupAccumulator(); |
| 485 Node* node = NewNode(op, context, value); | 574 NewNode(op, context, value); |
| 486 CHECK(node != nullptr); | |
| 487 environment()->BindAccumulator(value); | |
| 488 } | 575 } |
| 489 | 576 |
| 490 | 577 |
| 491 void BytecodeGraphBuilder::BuildNamedLoad( | 578 void BytecodeGraphBuilder::BuildNamedLoad( |
| 492 const interpreter::BytecodeArrayIterator& iterator) { | 579 const interpreter::BytecodeArrayIterator& iterator) { |
| 580 FrameStateBeforeAndAfter states(this, iterator); | |
| 493 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 581 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 494 Handle<Name> name = | 582 Handle<Name> name = |
| 495 Handle<Name>::cast(iterator.GetConstantForIndexOperand(1)); | 583 Handle<Name>::cast(iterator.GetConstantForIndexOperand(1)); |
| 496 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2)); | 584 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2)); |
| 497 | 585 |
| 498 const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback); | 586 const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback); |
| 499 Node* node = NewNode(op, object, BuildLoadFeedbackVector()); | 587 Node* node = NewNode(op, object, BuildLoadFeedbackVector()); |
| 500 AddEmptyFrameStateInputs(node); | 588 states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
| 501 environment()->BindAccumulator(node); | 589 environment()->BindAccumulator(node); |
| 502 } | 590 } |
| 503 | 591 |
| 504 | 592 |
| 505 void BytecodeGraphBuilder::VisitLoadICSloppy( | 593 void BytecodeGraphBuilder::VisitLoadICSloppy( |
| 506 const interpreter::BytecodeArrayIterator& iterator) { | 594 const interpreter::BytecodeArrayIterator& iterator) { |
| 507 DCHECK(is_sloppy(language_mode())); | 595 DCHECK(is_sloppy(language_mode())); |
| 508 BuildNamedLoad(iterator); | 596 BuildNamedLoad(iterator); |
| 509 } | 597 } |
| 510 | 598 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 525 | 613 |
| 526 void BytecodeGraphBuilder::VisitLoadICStrictWide( | 614 void BytecodeGraphBuilder::VisitLoadICStrictWide( |
| 527 const interpreter::BytecodeArrayIterator& iterator) { | 615 const interpreter::BytecodeArrayIterator& iterator) { |
| 528 DCHECK(is_strict(language_mode())); | 616 DCHECK(is_strict(language_mode())); |
| 529 BuildNamedLoad(iterator); | 617 BuildNamedLoad(iterator); |
| 530 } | 618 } |
| 531 | 619 |
| 532 | 620 |
| 533 void BytecodeGraphBuilder::BuildKeyedLoad( | 621 void BytecodeGraphBuilder::BuildKeyedLoad( |
| 534 const interpreter::BytecodeArrayIterator& iterator) { | 622 const interpreter::BytecodeArrayIterator& iterator) { |
| 623 FrameStateBeforeAndAfter states(this, iterator); | |
| 535 Node* key = environment()->LookupAccumulator(); | 624 Node* key = environment()->LookupAccumulator(); |
| 536 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 625 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 537 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); | 626 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1)); |
| 538 | 627 |
| 539 const Operator* op = javascript()->LoadProperty(language_mode(), feedback); | 628 const Operator* op = javascript()->LoadProperty(language_mode(), feedback); |
| 540 Node* node = NewNode(op, object, key, BuildLoadFeedbackVector()); | 629 Node* node = NewNode(op, object, key, BuildLoadFeedbackVector()); |
| 541 AddEmptyFrameStateInputs(node); | 630 states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
| 542 environment()->BindAccumulator(node); | 631 environment()->BindAccumulator(node); |
| 543 } | 632 } |
| 544 | 633 |
| 545 | 634 |
| 546 void BytecodeGraphBuilder::VisitKeyedLoadICSloppy( | 635 void BytecodeGraphBuilder::VisitKeyedLoadICSloppy( |
| 547 const interpreter::BytecodeArrayIterator& iterator) { | 636 const interpreter::BytecodeArrayIterator& iterator) { |
| 548 DCHECK(is_sloppy(language_mode())); | 637 DCHECK(is_sloppy(language_mode())); |
| 549 BuildKeyedLoad(iterator); | 638 BuildKeyedLoad(iterator); |
| 550 } | 639 } |
| 551 | 640 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 566 | 655 |
| 567 void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide( | 656 void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide( |
| 568 const interpreter::BytecodeArrayIterator& iterator) { | 657 const interpreter::BytecodeArrayIterator& iterator) { |
| 569 DCHECK(is_strict(language_mode())); | 658 DCHECK(is_strict(language_mode())); |
| 570 BuildKeyedLoad(iterator); | 659 BuildKeyedLoad(iterator); |
| 571 } | 660 } |
| 572 | 661 |
| 573 | 662 |
| 574 void BytecodeGraphBuilder::BuildNamedStore( | 663 void BytecodeGraphBuilder::BuildNamedStore( |
| 575 const interpreter::BytecodeArrayIterator& iterator) { | 664 const interpreter::BytecodeArrayIterator& iterator) { |
| 665 FrameStateBeforeAndAfter states(this, iterator); | |
| 576 Node* value = environment()->LookupAccumulator(); | 666 Node* value = environment()->LookupAccumulator(); |
| 577 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 667 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 578 Handle<Name> name = | 668 Handle<Name> name = |
| 579 Handle<Name>::cast(iterator.GetConstantForIndexOperand(1)); | 669 Handle<Name>::cast(iterator.GetConstantForIndexOperand(1)); |
| 580 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2)); | 670 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2)); |
| 581 | 671 |
| 582 const Operator* op = | 672 const Operator* op = |
| 583 javascript()->StoreNamed(language_mode(), name, feedback); | 673 javascript()->StoreNamed(language_mode(), name, feedback); |
| 584 Node* node = NewNode(op, object, value, BuildLoadFeedbackVector()); | 674 Node* node = NewNode(op, object, value, BuildLoadFeedbackVector()); |
| 585 AddEmptyFrameStateInputs(node); | 675 states.AddToNode(node, AccumulatorUpdateMode::kOutputIgnored); |
| 586 environment()->BindAccumulator(value); | |
| 587 } | 676 } |
| 588 | 677 |
| 589 | 678 |
| 590 void BytecodeGraphBuilder::VisitStoreICSloppy( | 679 void BytecodeGraphBuilder::VisitStoreICSloppy( |
| 591 const interpreter::BytecodeArrayIterator& iterator) { | 680 const interpreter::BytecodeArrayIterator& iterator) { |
| 592 DCHECK(is_sloppy(language_mode())); | 681 DCHECK(is_sloppy(language_mode())); |
| 593 BuildNamedStore(iterator); | 682 BuildNamedStore(iterator); |
| 594 } | 683 } |
| 595 | 684 |
| 596 | 685 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 610 | 699 |
| 611 void BytecodeGraphBuilder::VisitStoreICStrictWide( | 700 void BytecodeGraphBuilder::VisitStoreICStrictWide( |
| 612 const interpreter::BytecodeArrayIterator& iterator) { | 701 const interpreter::BytecodeArrayIterator& iterator) { |
| 613 DCHECK(is_strict(language_mode())); | 702 DCHECK(is_strict(language_mode())); |
| 614 BuildNamedStore(iterator); | 703 BuildNamedStore(iterator); |
| 615 } | 704 } |
| 616 | 705 |
| 617 | 706 |
| 618 void BytecodeGraphBuilder::BuildKeyedStore( | 707 void BytecodeGraphBuilder::BuildKeyedStore( |
| 619 const interpreter::BytecodeArrayIterator& iterator) { | 708 const interpreter::BytecodeArrayIterator& iterator) { |
| 709 FrameStateBeforeAndAfter states(this, iterator); | |
| 620 Node* value = environment()->LookupAccumulator(); | 710 Node* value = environment()->LookupAccumulator(); |
| 621 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 711 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 622 Node* key = environment()->LookupRegister(iterator.GetRegisterOperand(1)); | 712 Node* key = environment()->LookupRegister(iterator.GetRegisterOperand(1)); |
| 623 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2)); | 713 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2)); |
| 624 | 714 |
| 625 const Operator* op = javascript()->StoreProperty(language_mode(), feedback); | 715 const Operator* op = javascript()->StoreProperty(language_mode(), feedback); |
| 626 Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector()); | 716 Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector()); |
| 627 AddEmptyFrameStateInputs(node); | 717 states.AddToNode(node, AccumulatorUpdateMode::kOutputIgnored); |
| 628 environment()->BindAccumulator(value); | |
| 629 } | 718 } |
| 630 | 719 |
| 631 | 720 |
| 632 void BytecodeGraphBuilder::VisitKeyedStoreICSloppy( | 721 void BytecodeGraphBuilder::VisitKeyedStoreICSloppy( |
| 633 const interpreter::BytecodeArrayIterator& iterator) { | 722 const interpreter::BytecodeArrayIterator& iterator) { |
| 634 DCHECK(is_sloppy(language_mode())); | 723 DCHECK(is_sloppy(language_mode())); |
| 635 BuildKeyedStore(iterator); | 724 BuildKeyedStore(iterator); |
| 636 } | 725 } |
| 637 | 726 |
| 638 | 727 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 | 762 |
| 674 | 763 |
| 675 void BytecodeGraphBuilder::VisitCreateClosure( | 764 void BytecodeGraphBuilder::VisitCreateClosure( |
| 676 const interpreter::BytecodeArrayIterator& iterator) { | 765 const interpreter::BytecodeArrayIterator& iterator) { |
| 677 Handle<SharedFunctionInfo> shared_info = | 766 Handle<SharedFunctionInfo> shared_info = |
| 678 Handle<SharedFunctionInfo>::cast(iterator.GetConstantForIndexOperand(0)); | 767 Handle<SharedFunctionInfo>::cast(iterator.GetConstantForIndexOperand(0)); |
| 679 PretenureFlag tenured = | 768 PretenureFlag tenured = |
| 680 iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED; | 769 iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED; |
| 681 const Operator* op = javascript()->CreateClosure(shared_info, tenured); | 770 const Operator* op = javascript()->CreateClosure(shared_info, tenured); |
| 682 Node* closure = NewNode(op); | 771 Node* closure = NewNode(op); |
| 683 AddEmptyFrameStateInputs(closure); | |
| 684 environment()->BindAccumulator(closure); | 772 environment()->BindAccumulator(closure); |
| 685 } | 773 } |
| 686 | 774 |
| 687 | 775 |
| 688 void BytecodeGraphBuilder::VisitCreateClosureWide( | 776 void BytecodeGraphBuilder::VisitCreateClosureWide( |
| 689 const interpreter::BytecodeArrayIterator& iterator) { | 777 const interpreter::BytecodeArrayIterator& iterator) { |
| 690 VisitCreateClosure(iterator); | 778 VisitCreateClosure(iterator); |
| 691 } | 779 } |
| 692 | 780 |
| 693 | 781 |
| 694 void BytecodeGraphBuilder::VisitCreateMappedArguments( | 782 void BytecodeGraphBuilder::VisitCreateMappedArguments( |
| 695 const interpreter::BytecodeArrayIterator& iterator) { | 783 const interpreter::BytecodeArrayIterator& iterator) { |
| 696 UNIMPLEMENTED(); | 784 UNIMPLEMENTED(); |
| 697 } | 785 } |
| 698 | 786 |
| 699 | 787 |
| 700 void BytecodeGraphBuilder::VisitCreateUnmappedArguments( | 788 void BytecodeGraphBuilder::VisitCreateUnmappedArguments( |
| 701 const interpreter::BytecodeArrayIterator& iterator) { | 789 const interpreter::BytecodeArrayIterator& iterator) { |
| 702 UNIMPLEMENTED(); | 790 UNIMPLEMENTED(); |
| 703 } | 791 } |
| 704 | 792 |
| 705 | 793 |
| 706 void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) { | 794 void BytecodeGraphBuilder::BuildCreateLiteral( |
| 795 const Operator* op, const interpreter::BytecodeArrayIterator& iterator) { | |
| 796 FrameStateBeforeAndAfter states(this, iterator); | |
| 707 Node* literal = NewNode(op, GetFunctionClosure()); | 797 Node* literal = NewNode(op, GetFunctionClosure()); |
| 708 AddEmptyFrameStateInputs(literal); | 798 states.AddToNode(literal, AccumulatorUpdateMode::kOutputInAccumulator); |
| 709 environment()->BindAccumulator(literal); | 799 environment()->BindAccumulator(literal); |
| 710 } | 800 } |
| 711 | 801 |
| 712 | 802 |
| 713 void BytecodeGraphBuilder::BuildCreateRegExpLiteral( | 803 void BytecodeGraphBuilder::BuildCreateRegExpLiteral( |
| 714 const interpreter::BytecodeArrayIterator& iterator) { | 804 const interpreter::BytecodeArrayIterator& iterator) { |
| 715 Handle<String> constant_pattern = | 805 Handle<String> constant_pattern = |
| 716 Handle<String>::cast(iterator.GetConstantForIndexOperand(0)); | 806 Handle<String>::cast(iterator.GetConstantForIndexOperand(0)); |
| 717 int literal_index = iterator.GetIndexOperand(1); | 807 int literal_index = iterator.GetIndexOperand(1); |
| 718 int literal_flags = iterator.GetImmediateOperand(2); | 808 int literal_flags = iterator.GetImmediateOperand(2); |
| 719 const Operator* op = javascript()->CreateLiteralRegExp( | 809 const Operator* op = javascript()->CreateLiteralRegExp( |
| 720 constant_pattern, literal_flags, literal_index); | 810 constant_pattern, literal_flags, literal_index); |
| 721 BuildCreateLiteral(op); | 811 BuildCreateLiteral(op, iterator); |
| 722 } | 812 } |
| 723 | 813 |
| 724 | 814 |
| 725 void BytecodeGraphBuilder::VisitCreateRegExpLiteral( | 815 void BytecodeGraphBuilder::VisitCreateRegExpLiteral( |
| 726 const interpreter::BytecodeArrayIterator& iterator) { | 816 const interpreter::BytecodeArrayIterator& iterator) { |
| 727 BuildCreateRegExpLiteral(iterator); | 817 BuildCreateRegExpLiteral(iterator); |
| 728 } | 818 } |
| 729 | 819 |
| 730 | 820 |
| 731 void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide( | 821 void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide( |
| 732 const interpreter::BytecodeArrayIterator& iterator) { | 822 const interpreter::BytecodeArrayIterator& iterator) { |
| 733 BuildCreateRegExpLiteral(iterator); | 823 BuildCreateRegExpLiteral(iterator); |
| 734 } | 824 } |
| 735 | 825 |
| 736 | 826 |
| 737 void BytecodeGraphBuilder::BuildCreateArrayLiteral( | 827 void BytecodeGraphBuilder::BuildCreateArrayLiteral( |
| 738 const interpreter::BytecodeArrayIterator& iterator) { | 828 const interpreter::BytecodeArrayIterator& iterator) { |
| 739 Handle<FixedArray> constant_elements = | 829 Handle<FixedArray> constant_elements = |
| 740 Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0)); | 830 Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0)); |
| 741 int literal_index = iterator.GetIndexOperand(1); | 831 int literal_index = iterator.GetIndexOperand(1); |
| 742 int literal_flags = iterator.GetImmediateOperand(2); | 832 int literal_flags = iterator.GetImmediateOperand(2); |
| 743 const Operator* op = javascript()->CreateLiteralArray( | 833 const Operator* op = javascript()->CreateLiteralArray( |
| 744 constant_elements, literal_flags, literal_index); | 834 constant_elements, literal_flags, literal_index); |
| 745 BuildCreateLiteral(op); | 835 BuildCreateLiteral(op, iterator); |
| 746 } | 836 } |
| 747 | 837 |
| 748 | 838 |
| 749 void BytecodeGraphBuilder::VisitCreateArrayLiteral( | 839 void BytecodeGraphBuilder::VisitCreateArrayLiteral( |
| 750 const interpreter::BytecodeArrayIterator& iterator) { | 840 const interpreter::BytecodeArrayIterator& iterator) { |
| 751 BuildCreateArrayLiteral(iterator); | 841 BuildCreateArrayLiteral(iterator); |
| 752 } | 842 } |
| 753 | 843 |
| 754 | 844 |
| 755 void BytecodeGraphBuilder::VisitCreateArrayLiteralWide( | 845 void BytecodeGraphBuilder::VisitCreateArrayLiteralWide( |
| 756 const interpreter::BytecodeArrayIterator& iterator) { | 846 const interpreter::BytecodeArrayIterator& iterator) { |
| 757 BuildCreateArrayLiteral(iterator); | 847 BuildCreateArrayLiteral(iterator); |
| 758 } | 848 } |
| 759 | 849 |
| 760 | 850 |
| 761 void BytecodeGraphBuilder::BuildCreateObjectLiteral( | 851 void BytecodeGraphBuilder::BuildCreateObjectLiteral( |
| 762 const interpreter::BytecodeArrayIterator& iterator) { | 852 const interpreter::BytecodeArrayIterator& iterator) { |
| 763 Handle<FixedArray> constant_properties = | 853 Handle<FixedArray> constant_properties = |
| 764 Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0)); | 854 Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0)); |
| 765 int literal_index = iterator.GetIndexOperand(1); | 855 int literal_index = iterator.GetIndexOperand(1); |
| 766 int literal_flags = iterator.GetImmediateOperand(2); | 856 int literal_flags = iterator.GetImmediateOperand(2); |
| 767 const Operator* op = javascript()->CreateLiteralObject( | 857 const Operator* op = javascript()->CreateLiteralObject( |
| 768 constant_properties, literal_flags, literal_index); | 858 constant_properties, literal_flags, literal_index); |
| 769 BuildCreateLiteral(op); | 859 BuildCreateLiteral(op, iterator); |
| 770 } | 860 } |
| 771 | 861 |
| 772 | 862 |
| 773 void BytecodeGraphBuilder::VisitCreateObjectLiteral( | 863 void BytecodeGraphBuilder::VisitCreateObjectLiteral( |
| 774 const interpreter::BytecodeArrayIterator& iterator) { | 864 const interpreter::BytecodeArrayIterator& iterator) { |
| 775 BuildCreateObjectLiteral(iterator); | 865 BuildCreateObjectLiteral(iterator); |
| 776 } | 866 } |
| 777 | 867 |
| 778 | 868 |
| 779 void BytecodeGraphBuilder::VisitCreateObjectLiteralWide( | 869 void BytecodeGraphBuilder::VisitCreateObjectLiteralWide( |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 794 all[i] = environment()->LookupRegister( | 884 all[i] = environment()->LookupRegister( |
| 795 interpreter::Register(receiver_index + i - 1)); | 885 interpreter::Register(receiver_index + i - 1)); |
| 796 } | 886 } |
| 797 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); | 887 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); |
| 798 return value; | 888 return value; |
| 799 } | 889 } |
| 800 | 890 |
| 801 | 891 |
| 802 void BytecodeGraphBuilder::BuildCall( | 892 void BytecodeGraphBuilder::BuildCall( |
| 803 const interpreter::BytecodeArrayIterator& iterator) { | 893 const interpreter::BytecodeArrayIterator& iterator) { |
| 894 FrameStateBeforeAndAfter states(this, iterator); | |
| 804 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver | 895 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver |
| 805 // register has been loaded with null / undefined explicitly or we are sure it | 896 // register has been loaded with null / undefined explicitly or we are sure it |
| 806 // is not null / undefined. | 897 // is not null / undefined. |
| 807 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; | 898 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
| 808 Node* callee = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 899 Node* callee = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 809 interpreter::Register receiver = iterator.GetRegisterOperand(1); | 900 interpreter::Register receiver = iterator.GetRegisterOperand(1); |
| 810 size_t arg_count = iterator.GetCountOperand(2); | 901 size_t arg_count = iterator.GetCountOperand(2); |
| 811 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3)); | 902 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3)); |
| 812 | 903 |
| 813 const Operator* call = javascript()->CallFunction( | 904 const Operator* call = javascript()->CallFunction( |
| 814 arg_count + 2, language_mode(), feedback, receiver_hint); | 905 arg_count + 2, language_mode(), feedback, receiver_hint); |
| 815 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2); | 906 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2); |
| 816 AddEmptyFrameStateInputs(value); | 907 states.AddToNode(value, AccumulatorUpdateMode::kOutputInAccumulator); |
| 817 environment()->BindAccumulator(value); | 908 environment()->BindAccumulator(value); |
| 818 } | 909 } |
| 819 | 910 |
| 820 | 911 |
| 821 void BytecodeGraphBuilder::VisitCall( | 912 void BytecodeGraphBuilder::VisitCall( |
| 822 const interpreter::BytecodeArrayIterator& iterator) { | 913 const interpreter::BytecodeArrayIterator& iterator) { |
| 823 BuildCall(iterator); | 914 BuildCall(iterator); |
| 824 } | 915 } |
| 825 | 916 |
| 826 | 917 |
| 827 void BytecodeGraphBuilder::VisitCallWide( | 918 void BytecodeGraphBuilder::VisitCallWide( |
| 828 const interpreter::BytecodeArrayIterator& iterator) { | 919 const interpreter::BytecodeArrayIterator& iterator) { |
| 829 BuildCall(iterator); | 920 BuildCall(iterator); |
| 830 } | 921 } |
| 831 | 922 |
| 832 | 923 |
| 833 void BytecodeGraphBuilder::VisitCallJSRuntime( | 924 void BytecodeGraphBuilder::VisitCallJSRuntime( |
| 834 const interpreter::BytecodeArrayIterator& iterator) { | 925 const interpreter::BytecodeArrayIterator& iterator) { |
| 926 FrameStateBeforeAndAfter states(this, iterator); | |
| 835 Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0)); | 927 Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0)); |
| 836 interpreter::Register receiver = iterator.GetRegisterOperand(1); | 928 interpreter::Register receiver = iterator.GetRegisterOperand(1); |
| 837 size_t arg_count = iterator.GetCountOperand(2); | 929 size_t arg_count = iterator.GetCountOperand(2); |
| 838 | 930 |
| 839 // Create node to perform the JS runtime call. | 931 // Create node to perform the JS runtime call. |
| 840 const Operator* call = | 932 const Operator* call = |
| 841 javascript()->CallFunction(arg_count + 2, language_mode()); | 933 javascript()->CallFunction(arg_count + 2, language_mode()); |
| 842 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2); | 934 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2); |
| 843 AddEmptyFrameStateInputs(value); | 935 states.AddToNode(value, AccumulatorUpdateMode::kOutputInAccumulator); |
| 844 environment()->BindAccumulator(value); | 936 environment()->BindAccumulator(value); |
| 845 } | 937 } |
| 846 | 938 |
| 847 | 939 |
| 848 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments( | 940 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments( |
| 849 const Operator* call_runtime_op, interpreter::Register first_arg, | 941 const Operator* call_runtime_op, interpreter::Register first_arg, |
| 850 size_t arity) { | 942 size_t arity) { |
| 851 Node** all = info()->zone()->NewArray<Node*>(arity); | 943 Node** all = info()->zone()->NewArray<Node*>(arity); |
| 852 int first_arg_index = first_arg.index(); | 944 int first_arg_index = first_arg.index(); |
| 853 for (int i = 0; i < static_cast<int>(arity); ++i) { | 945 for (int i = 0; i < static_cast<int>(arity); ++i) { |
| 854 all[i] = environment()->LookupRegister( | 946 all[i] = environment()->LookupRegister( |
| 855 interpreter::Register(first_arg_index + i)); | 947 interpreter::Register(first_arg_index + i)); |
| 856 } | 948 } |
| 857 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false); | 949 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false); |
| 858 return value; | 950 return value; |
| 859 } | 951 } |
| 860 | 952 |
| 861 | 953 |
| 862 void BytecodeGraphBuilder::VisitCallRuntime( | 954 void BytecodeGraphBuilder::VisitCallRuntime( |
| 863 const interpreter::BytecodeArrayIterator& iterator) { | 955 const interpreter::BytecodeArrayIterator& iterator) { |
| 956 FrameStateBeforeAndAfter states(this, iterator); | |
| 864 Runtime::FunctionId functionId = | 957 Runtime::FunctionId functionId = |
| 865 static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0)); | 958 static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0)); |
| 866 interpreter::Register first_arg = iterator.GetRegisterOperand(1); | 959 interpreter::Register first_arg = iterator.GetRegisterOperand(1); |
| 867 size_t arg_count = iterator.GetCountOperand(2); | 960 size_t arg_count = iterator.GetCountOperand(2); |
| 868 | 961 |
| 869 // Create node to perform the runtime call. | 962 // Create node to perform the runtime call. |
| 870 const Operator* call = javascript()->CallRuntime(functionId, arg_count); | 963 const Operator* call = javascript()->CallRuntime(functionId, arg_count); |
| 871 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count); | 964 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count); |
| 872 AddEmptyFrameStateInputs(value); | 965 states.AddToNode(value, AccumulatorUpdateMode::kOutputInAccumulator); |
| 873 environment()->BindAccumulator(value); | 966 environment()->BindAccumulator(value); |
| 874 } | 967 } |
| 875 | 968 |
| 876 | 969 |
| 877 Node* BytecodeGraphBuilder::ProcessCallNewArguments( | 970 Node* BytecodeGraphBuilder::ProcessCallNewArguments( |
| 878 const Operator* call_new_op, interpreter::Register callee, | 971 const Operator* call_new_op, interpreter::Register callee, |
| 879 interpreter::Register first_arg, size_t arity) { | 972 interpreter::Register first_arg, size_t arity) { |
| 880 Node** all = info()->zone()->NewArray<Node*>(arity); | 973 Node** all = info()->zone()->NewArray<Node*>(arity); |
| 881 all[0] = environment()->LookupRegister(callee); | 974 all[0] = environment()->LookupRegister(callee); |
| 882 int first_arg_index = first_arg.index(); | 975 int first_arg_index = first_arg.index(); |
| 883 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) { | 976 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) { |
| 884 all[i] = environment()->LookupRegister( | 977 all[i] = environment()->LookupRegister( |
| 885 interpreter::Register(first_arg_index + i - 1)); | 978 interpreter::Register(first_arg_index + i - 1)); |
| 886 } | 979 } |
| 887 // Original constructor is the same as the callee. | 980 // Original constructor is the same as the callee. |
| 888 all[arity - 1] = environment()->LookupRegister(callee); | 981 all[arity - 1] = environment()->LookupRegister(callee); |
| 889 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false); | 982 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false); |
| 890 return value; | 983 return value; |
| 891 } | 984 } |
| 892 | 985 |
| 893 | 986 |
| 894 void BytecodeGraphBuilder::VisitNew( | 987 void BytecodeGraphBuilder::VisitNew( |
| 895 const interpreter::BytecodeArrayIterator& iterator) { | 988 const interpreter::BytecodeArrayIterator& iterator) { |
| 989 FrameStateBeforeAndAfter states(this, iterator); | |
| 896 interpreter::Register callee = iterator.GetRegisterOperand(0); | 990 interpreter::Register callee = iterator.GetRegisterOperand(0); |
| 897 interpreter::Register first_arg = iterator.GetRegisterOperand(1); | 991 interpreter::Register first_arg = iterator.GetRegisterOperand(1); |
| 898 size_t arg_count = iterator.GetCountOperand(2); | 992 size_t arg_count = iterator.GetCountOperand(2); |
| 899 | 993 |
| 900 // TODO(turbofan): Pass the feedback here. | 994 // TODO(turbofan): Pass the feedback here. |
| 901 const Operator* call = javascript()->CallConstruct( | 995 const Operator* call = javascript()->CallConstruct( |
| 902 static_cast<int>(arg_count) + 2, VectorSlotPair()); | 996 static_cast<int>(arg_count) + 2, VectorSlotPair()); |
| 903 Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2); | 997 Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2); |
| 904 AddEmptyFrameStateInputs(value); | 998 states.AddToNode(value, AccumulatorUpdateMode::kOutputInAccumulator); |
| 905 environment()->BindAccumulator(value); | 999 environment()->BindAccumulator(value); |
| 906 } | 1000 } |
| 907 | 1001 |
| 908 | 1002 |
| 909 void BytecodeGraphBuilder::VisitThrow( | 1003 void BytecodeGraphBuilder::VisitThrow( |
| 910 const interpreter::BytecodeArrayIterator& iterator) { | 1004 const interpreter::BytecodeArrayIterator& iterator) { |
| 1005 FrameStateBeforeAndAfter states(this, iterator); | |
| 911 Node* value = environment()->LookupAccumulator(); | 1006 Node* value = environment()->LookupAccumulator(); |
| 912 // TODO(mythria): Change to Runtime::kThrow when we have deoptimization | 1007 // TODO(mythria): Change to Runtime::kThrow when we have deoptimization |
| 913 // information support in the interpreter. | 1008 // information support in the interpreter. |
| 914 NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), value); | 1009 NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), value); |
| 915 Node* control = NewNode(common()->Throw(), value); | 1010 Node* control = NewNode(common()->Throw(), value); |
| 1011 states.AddToNode(control, AccumulatorUpdateMode::kOutputIgnored); | |
| 916 UpdateControlDependencyToLeaveFunction(control); | 1012 UpdateControlDependencyToLeaveFunction(control); |
| 917 environment()->BindAccumulator(value); | |
| 918 } | 1013 } |
| 919 | 1014 |
| 920 | 1015 |
| 921 void BytecodeGraphBuilder::BuildBinaryOp( | 1016 void BytecodeGraphBuilder::BuildBinaryOp( |
| 922 const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { | 1017 const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { |
| 1018 FrameStateBeforeAndAfter states(this, iterator); | |
| 923 Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 1019 Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 924 Node* right = environment()->LookupAccumulator(); | 1020 Node* right = environment()->LookupAccumulator(); |
| 925 Node* node = NewNode(js_op, left, right); | 1021 Node* node = NewNode(js_op, left, right); |
| 926 | 1022 states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
| 927 AddEmptyFrameStateInputs(node); | |
| 928 environment()->BindAccumulator(node); | 1023 environment()->BindAccumulator(node); |
| 929 } | 1024 } |
| 930 | 1025 |
| 931 | 1026 |
| 932 void BytecodeGraphBuilder::VisitAdd( | 1027 void BytecodeGraphBuilder::VisitAdd( |
| 933 const interpreter::BytecodeArrayIterator& iterator) { | 1028 const interpreter::BytecodeArrayIterator& iterator) { |
| 934 BinaryOperationHints hints = BinaryOperationHints::Any(); | 1029 BinaryOperationHints hints = BinaryOperationHints::Any(); |
| 935 BuildBinaryOp(javascript()->Add(language_mode(), hints), iterator); | 1030 BuildBinaryOp(javascript()->Add(language_mode(), hints), iterator); |
| 936 } | 1031 } |
| 937 | 1032 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1002 void BytecodeGraphBuilder::VisitShiftRightLogical( | 1097 void BytecodeGraphBuilder::VisitShiftRightLogical( |
| 1003 const interpreter::BytecodeArrayIterator& iterator) { | 1098 const interpreter::BytecodeArrayIterator& iterator) { |
| 1004 BinaryOperationHints hints = BinaryOperationHints::Any(); | 1099 BinaryOperationHints hints = BinaryOperationHints::Any(); |
| 1005 BuildBinaryOp(javascript()->ShiftRightLogical(language_mode(), hints), | 1100 BuildBinaryOp(javascript()->ShiftRightLogical(language_mode(), hints), |
| 1006 iterator); | 1101 iterator); |
| 1007 } | 1102 } |
| 1008 | 1103 |
| 1009 | 1104 |
| 1010 void BytecodeGraphBuilder::VisitInc( | 1105 void BytecodeGraphBuilder::VisitInc( |
| 1011 const interpreter::BytecodeArrayIterator& iterator) { | 1106 const interpreter::BytecodeArrayIterator& iterator) { |
| 1107 FrameStateBeforeAndAfter states(this, iterator); | |
| 1012 const Operator* js_op = | 1108 const Operator* js_op = |
| 1013 javascript()->Add(language_mode(), BinaryOperationHints::Any()); | 1109 javascript()->Add(language_mode(), BinaryOperationHints::Any()); |
| 1014 Node* node = NewNode(js_op, environment()->LookupAccumulator(), | 1110 Node* node = NewNode(js_op, environment()->LookupAccumulator(), |
| 1015 jsgraph()->OneConstant()); | 1111 jsgraph()->OneConstant()); |
| 1016 | 1112 states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
| 1017 AddEmptyFrameStateInputs(node); | |
| 1018 environment()->BindAccumulator(node); | 1113 environment()->BindAccumulator(node); |
| 1019 } | 1114 } |
| 1020 | 1115 |
| 1021 | 1116 |
| 1022 void BytecodeGraphBuilder::VisitDec( | 1117 void BytecodeGraphBuilder::VisitDec( |
| 1023 const interpreter::BytecodeArrayIterator& iterator) { | 1118 const interpreter::BytecodeArrayIterator& iterator) { |
| 1119 FrameStateBeforeAndAfter states(this, iterator); | |
| 1024 const Operator* js_op = | 1120 const Operator* js_op = |
| 1025 javascript()->Subtract(language_mode(), BinaryOperationHints::Any()); | 1121 javascript()->Subtract(language_mode(), BinaryOperationHints::Any()); |
| 1026 Node* node = NewNode(js_op, environment()->LookupAccumulator(), | 1122 Node* node = NewNode(js_op, environment()->LookupAccumulator(), |
| 1027 jsgraph()->OneConstant()); | 1123 jsgraph()->OneConstant()); |
| 1028 | 1124 states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
| 1029 AddEmptyFrameStateInputs(node); | |
| 1030 environment()->BindAccumulator(node); | 1125 environment()->BindAccumulator(node); |
| 1031 } | 1126 } |
| 1032 | 1127 |
| 1033 | 1128 |
| 1034 void BytecodeGraphBuilder::VisitLogicalNot( | 1129 void BytecodeGraphBuilder::VisitLogicalNot( |
| 1035 const interpreter::BytecodeArrayIterator& iterator) { | 1130 const interpreter::BytecodeArrayIterator& iterator) { |
| 1036 Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), | 1131 Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), |
| 1037 environment()->LookupAccumulator()); | 1132 environment()->LookupAccumulator()); |
| 1038 Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value, | 1133 Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value, |
| 1039 jsgraph()->FalseConstant(), jsgraph()->TrueConstant()); | 1134 jsgraph()->FalseConstant(), jsgraph()->TrueConstant()); |
| 1040 environment()->BindAccumulator(node); | 1135 environment()->BindAccumulator(node); |
| 1041 } | 1136 } |
| 1042 | 1137 |
| 1043 | 1138 |
| 1044 void BytecodeGraphBuilder::VisitTypeOf( | 1139 void BytecodeGraphBuilder::VisitTypeOf( |
| 1045 const interpreter::BytecodeArrayIterator& iterator) { | 1140 const interpreter::BytecodeArrayIterator& iterator) { |
| 1046 Node* node = | 1141 Node* node = |
| 1047 NewNode(javascript()->TypeOf(), environment()->LookupAccumulator()); | 1142 NewNode(javascript()->TypeOf(), environment()->LookupAccumulator()); |
| 1048 environment()->BindAccumulator(node); | 1143 environment()->BindAccumulator(node); |
| 1049 } | 1144 } |
| 1050 | 1145 |
| 1051 | 1146 |
| 1052 void BytecodeGraphBuilder::BuildDelete( | 1147 void BytecodeGraphBuilder::BuildDelete( |
| 1053 const interpreter::BytecodeArrayIterator& iterator) { | 1148 const interpreter::BytecodeArrayIterator& iterator) { |
| 1149 FrameStateBeforeAndAfter states(this, iterator); | |
| 1054 Node* key = environment()->LookupAccumulator(); | 1150 Node* key = environment()->LookupAccumulator(); |
| 1055 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 1151 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 1056 | |
| 1057 Node* node = | 1152 Node* node = |
| 1058 NewNode(javascript()->DeleteProperty(language_mode()), object, key); | 1153 NewNode(javascript()->DeleteProperty(language_mode()), object, key); |
| 1059 AddEmptyFrameStateInputs(node); | 1154 states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
| 1060 environment()->BindAccumulator(node); | 1155 environment()->BindAccumulator(node); |
| 1061 } | 1156 } |
| 1062 | 1157 |
| 1063 | 1158 |
| 1064 void BytecodeGraphBuilder::VisitDeletePropertyStrict( | 1159 void BytecodeGraphBuilder::VisitDeletePropertyStrict( |
| 1065 const interpreter::BytecodeArrayIterator& iterator) { | 1160 const interpreter::BytecodeArrayIterator& iterator) { |
| 1066 DCHECK(is_strict(language_mode())); | 1161 DCHECK(is_strict(language_mode())); |
| 1067 BuildDelete(iterator); | 1162 BuildDelete(iterator); |
| 1068 } | 1163 } |
| 1069 | 1164 |
| 1070 | 1165 |
| 1071 void BytecodeGraphBuilder::VisitDeletePropertySloppy( | 1166 void BytecodeGraphBuilder::VisitDeletePropertySloppy( |
| 1072 const interpreter::BytecodeArrayIterator& iterator) { | 1167 const interpreter::BytecodeArrayIterator& iterator) { |
| 1073 DCHECK(is_sloppy(language_mode())); | 1168 DCHECK(is_sloppy(language_mode())); |
| 1074 BuildDelete(iterator); | 1169 BuildDelete(iterator); |
| 1075 } | 1170 } |
| 1076 | 1171 |
| 1077 | 1172 |
| 1078 void BytecodeGraphBuilder::BuildCompareOp( | 1173 void BytecodeGraphBuilder::BuildCompareOp( |
| 1079 const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { | 1174 const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { |
| 1175 FrameStateBeforeAndAfter states(this, iterator); | |
| 1080 Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 1176 Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 1081 Node* right = environment()->LookupAccumulator(); | 1177 Node* right = environment()->LookupAccumulator(); |
| 1082 Node* node = NewNode(js_op, left, right); | 1178 Node* node = NewNode(js_op, left, right); |
| 1083 | 1179 states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
| 1084 AddEmptyFrameStateInputs(node); | |
| 1085 environment()->BindAccumulator(node); | 1180 environment()->BindAccumulator(node); |
| 1086 } | 1181 } |
| 1087 | 1182 |
| 1088 | 1183 |
| 1089 void BytecodeGraphBuilder::VisitTestEqual( | 1184 void BytecodeGraphBuilder::VisitTestEqual( |
| 1090 const interpreter::BytecodeArrayIterator& iterator) { | 1185 const interpreter::BytecodeArrayIterator& iterator) { |
| 1091 BuildCompareOp(javascript()->Equal(), iterator); | 1186 BuildCompareOp(javascript()->Equal(), iterator); |
| 1092 } | 1187 } |
| 1093 | 1188 |
| 1094 | 1189 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1141 | 1236 |
| 1142 | 1237 |
| 1143 void BytecodeGraphBuilder::VisitTestInstanceOf( | 1238 void BytecodeGraphBuilder::VisitTestInstanceOf( |
| 1144 const interpreter::BytecodeArrayIterator& iterator) { | 1239 const interpreter::BytecodeArrayIterator& iterator) { |
| 1145 BuildCompareOp(javascript()->InstanceOf(), iterator); | 1240 BuildCompareOp(javascript()->InstanceOf(), iterator); |
| 1146 } | 1241 } |
| 1147 | 1242 |
| 1148 | 1243 |
| 1149 void BytecodeGraphBuilder::BuildCastOperator( | 1244 void BytecodeGraphBuilder::BuildCastOperator( |
| 1150 const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { | 1245 const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { |
| 1246 FrameStateBeforeAndAfter states(this, iterator); | |
| 1151 Node* node = NewNode(js_op, environment()->LookupAccumulator()); | 1247 Node* node = NewNode(js_op, environment()->LookupAccumulator()); |
| 1152 AddEmptyFrameStateInputs(node); | 1248 states.AddToNode(node, AccumulatorUpdateMode::kOutputInAccumulator); |
| 1153 environment()->BindAccumulator(node); | 1249 environment()->BindAccumulator(node); |
| 1154 } | 1250 } |
| 1155 | 1251 |
| 1156 | 1252 |
| 1157 void BytecodeGraphBuilder::VisitToName( | 1253 void BytecodeGraphBuilder::VisitToName( |
| 1158 const interpreter::BytecodeArrayIterator& iterator) { | 1254 const interpreter::BytecodeArrayIterator& iterator) { |
| 1159 BuildCastOperator(javascript()->ToName(), iterator); | 1255 BuildCastOperator(javascript()->ToName(), iterator); |
| 1160 } | 1256 } |
| 1161 | 1257 |
| 1162 | 1258 |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1378 | 1474 |
| 1379 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { | 1475 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { |
| 1380 if (environment()->IsMarkedAsUnreachable()) return; | 1476 if (environment()->IsMarkedAsUnreachable()) return; |
| 1381 environment()->MarkAsUnreachable(); | 1477 environment()->MarkAsUnreachable(); |
| 1382 exit_controls_.push_back(exit); | 1478 exit_controls_.push_back(exit); |
| 1383 } | 1479 } |
| 1384 | 1480 |
| 1385 } // namespace compiler | 1481 } // namespace compiler |
| 1386 } // namespace internal | 1482 } // namespace internal |
| 1387 } // namespace v8 | 1483 } // namespace v8 |
| OLD | NEW |