| 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/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" |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 | 348 |
| 349 // Connect to the loop end. | 349 // Connect to the loop end. |
| 350 Node* terminate = builder()->graph()->NewNode( | 350 Node* terminate = builder()->graph()->NewNode( |
| 351 builder()->common()->Terminate(), effect, control); | 351 builder()->common()->Terminate(), effect, control); |
| 352 builder()->exit_controls_.push_back(terminate); | 352 builder()->exit_controls_.push_back(terminate); |
| 353 } | 353 } |
| 354 | 354 |
| 355 | 355 |
| 356 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( | 356 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( |
| 357 Node** state_values, int offset, int count) { | 357 Node** state_values, int offset, int count) { |
| 358 if (!builder()->info()->is_deoptimization_enabled()) { | 358 if (!builder()->deoptimization_enabled_) { |
| 359 return false; | 359 return false; |
| 360 } | 360 } |
| 361 if (*state_values == nullptr) { | 361 if (*state_values == nullptr) { |
| 362 return true; | 362 return true; |
| 363 } | 363 } |
| 364 DCHECK_EQ((*state_values)->InputCount(), count); | 364 DCHECK_EQ((*state_values)->InputCount(), count); |
| 365 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); | 365 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); |
| 366 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | 366 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
| 367 for (int i = 0; i < count; i++) { | 367 for (int i = 0; i < count; i++) { |
| 368 if ((*state_values)->InputAt(i) != env_values[i]) { | 368 if ((*state_values)->InputAt(i) != env_values[i]) { |
| 369 return true; | 369 return true; |
| 370 } | 370 } |
| 371 } | 371 } |
| 372 return false; | 372 return false; |
| 373 } | 373 } |
| 374 | 374 |
| 375 | 375 |
| 376 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 376 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
| 377 int offset, | 377 int offset, |
| 378 int count) { | 378 int count) { |
| 379 if (StateValuesRequireUpdate(state_values, offset, count)) { | 379 if (StateValuesRequireUpdate(state_values, offset, count)) { |
| 380 const Operator* op = common()->StateValues(count); | 380 const Operator* op = common()->StateValues(count); |
| 381 (*state_values) = graph()->NewNode(op, count, &values()->at(offset)); | 381 (*state_values) = graph()->NewNode(op, count, &values()->at(offset)); |
| 382 } | 382 } |
| 383 } | 383 } |
| 384 | 384 |
| 385 | 385 |
| 386 Node* BytecodeGraphBuilder::Environment::Checkpoint( | 386 Node* BytecodeGraphBuilder::Environment::Checkpoint( |
| 387 BailoutId bailout_id, OutputFrameStateCombine combine) { | 387 BailoutId bailout_id, OutputFrameStateCombine combine) { |
| 388 if (!builder()->info()->is_deoptimization_enabled()) { | 388 if (!builder()->deoptimization_enabled_) { |
| 389 return builder()->jsgraph()->EmptyFrameState(); | 389 return builder()->jsgraph()->EmptyFrameState(); |
| 390 } | 390 } |
| 391 | 391 |
| 392 // TODO(rmcilroy): Consider using StateValuesCache for some state values. | 392 // TODO(rmcilroy): Consider using StateValuesCache for some state values. |
| 393 UpdateStateValues(¶meters_state_values_, 0, parameter_count()); | 393 UpdateStateValues(¶meters_state_values_, 0, parameter_count()); |
| 394 UpdateStateValues(®isters_state_values_, register_base(), | 394 UpdateStateValues(®isters_state_values_, register_base(), |
| 395 register_count()); | 395 register_count()); |
| 396 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1); | 396 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1); |
| 397 | 397 |
| 398 const Operator* op = common()->FrameState( | 398 const Operator* op = common()->FrameState( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 416 return false; | 416 return false; |
| 417 } | 417 } |
| 418 } | 418 } |
| 419 } | 419 } |
| 420 return true; | 420 return true; |
| 421 } | 421 } |
| 422 | 422 |
| 423 | 423 |
| 424 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate( | 424 bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate( |
| 425 int output_poke_offset, int output_poke_count) { | 425 int output_poke_offset, int output_poke_count) { |
| 426 if (!builder()->info()->is_deoptimization_enabled()) return true; | 426 if (!builder()->deoptimization_enabled_) return true; |
| 427 // Poke offset is relative to the top of the stack (i.e., the accumulator). | 427 // Poke offset is relative to the top of the stack (i.e., the accumulator). |
| 428 int output_poke_start = accumulator_base() - output_poke_offset; | 428 int output_poke_start = accumulator_base() - output_poke_offset; |
| 429 int output_poke_end = output_poke_start + output_poke_count; | 429 int output_poke_end = output_poke_start + output_poke_count; |
| 430 return StateValuesAreUpToDate(¶meters_state_values_, 0, parameter_count(), | 430 return StateValuesAreUpToDate(¶meters_state_values_, 0, parameter_count(), |
| 431 output_poke_start, output_poke_end) && | 431 output_poke_start, output_poke_end) && |
| 432 StateValuesAreUpToDate(®isters_state_values_, register_base(), | 432 StateValuesAreUpToDate(®isters_state_values_, register_base(), |
| 433 register_count(), output_poke_start, | 433 register_count(), output_poke_start, |
| 434 output_poke_end) && | 434 output_poke_end) && |
| 435 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(), | 435 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(), |
| 436 1, output_poke_start, output_poke_end); | 436 1, output_poke_start, output_poke_end); |
| 437 } | 437 } |
| 438 | 438 |
| 439 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, | 439 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, |
| 440 CompilationInfo* compilation_info, | 440 CompilationInfo* info, |
| 441 JSGraph* jsgraph) | 441 JSGraph* jsgraph) |
| 442 : local_zone_(local_zone), | 442 : local_zone_(local_zone), |
| 443 info_(compilation_info), | |
| 444 jsgraph_(jsgraph), | 443 jsgraph_(jsgraph), |
| 445 bytecode_array_(handle(info()->shared_info()->bytecode_array())), | 444 bytecode_array_(handle(info->shared_info()->bytecode_array())), |
| 446 exception_handler_table_( | 445 exception_handler_table_( |
| 447 handle(HandlerTable::cast(bytecode_array()->handler_table()))), | 446 handle(HandlerTable::cast(bytecode_array()->handler_table()))), |
| 447 feedback_vector_(info->feedback_vector()), |
| 448 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 448 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
| 449 FrameStateType::kInterpretedFunction, | 449 FrameStateType::kInterpretedFunction, |
| 450 bytecode_array()->parameter_count(), | 450 bytecode_array()->parameter_count(), |
| 451 bytecode_array()->register_count(), info()->shared_info(), | 451 bytecode_array()->register_count(), info->shared_info(), |
| 452 CALL_MAINTAINS_NATIVE_CONTEXT)), | 452 CALL_MAINTAINS_NATIVE_CONTEXT)), |
| 453 deoptimization_enabled_(info->is_deoptimization_enabled()), |
| 453 merge_environments_(local_zone), | 454 merge_environments_(local_zone), |
| 454 exception_handlers_(local_zone), | 455 exception_handlers_(local_zone), |
| 455 current_exception_handler_(0), | 456 current_exception_handler_(0), |
| 456 input_buffer_size_(0), | 457 input_buffer_size_(0), |
| 457 input_buffer_(nullptr), | 458 input_buffer_(nullptr), |
| 458 exit_controls_(local_zone) {} | 459 exit_controls_(local_zone) {} |
| 459 | 460 |
| 460 Node* BytecodeGraphBuilder::GetNewTarget() { | 461 Node* BytecodeGraphBuilder::GetNewTarget() { |
| 461 if (!new_target_.is_set()) { | 462 if (!new_target_.is_set()) { |
| 462 int params = bytecode_array()->parameter_count(); | 463 int params = bytecode_array()->parameter_count(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 | 495 |
| 495 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) { | 496 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) { |
| 496 const Operator* op = | 497 const Operator* op = |
| 497 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); | 498 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); |
| 498 Node* native_context = NewNode(op, environment()->Context()); | 499 Node* native_context = NewNode(op, environment()->Context()); |
| 499 return NewNode(javascript()->LoadContext(0, index, true), native_context); | 500 return NewNode(javascript()->LoadContext(0, index, true), native_context); |
| 500 } | 501 } |
| 501 | 502 |
| 502 | 503 |
| 503 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { | 504 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { |
| 504 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); | |
| 505 FeedbackVectorSlot slot; | 505 FeedbackVectorSlot slot; |
| 506 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) { | 506 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) { |
| 507 slot = feedback_vector->ToSlot(slot_id); | 507 slot = feedback_vector()->ToSlot(slot_id); |
| 508 } | 508 } |
| 509 return VectorSlotPair(feedback_vector, slot); | 509 return VectorSlotPair(feedback_vector(), slot); |
| 510 } | 510 } |
| 511 | 511 |
| 512 bool BytecodeGraphBuilder::CreateGraph() { | 512 bool BytecodeGraphBuilder::CreateGraph() { |
| 513 // Set up the basic structure of the graph. Outputs for {Start} are | 513 // Set up the basic structure of the graph. Outputs for {Start} are |
| 514 // the formal parameters (including the receiver) plus context and | 514 // the formal parameters (including the receiver) plus context and |
| 515 // closure. | 515 // closure. |
| 516 | 516 |
| 517 // Set up the basic structure of the graph. Outputs for {Start} are the formal | 517 // Set up the basic structure of the graph. Outputs for {Start} are the formal |
| 518 // parameters (including the receiver) plus new target, number of arguments, | 518 // parameters (including the receiver) plus new target, number of arguments, |
| 519 // context and closure. | 519 // context and closure. |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 | 974 |
| 975 void BytecodeGraphBuilder::VisitCreateObjectLiteralWide() { | 975 void BytecodeGraphBuilder::VisitCreateObjectLiteralWide() { |
| 976 BuildCreateObjectLiteral(); | 976 BuildCreateObjectLiteral(); |
| 977 } | 977 } |
| 978 | 978 |
| 979 | 979 |
| 980 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, | 980 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
| 981 Node* callee, | 981 Node* callee, |
| 982 interpreter::Register receiver, | 982 interpreter::Register receiver, |
| 983 size_t arity) { | 983 size_t arity) { |
| 984 Node** all = info()->zone()->NewArray<Node*>(static_cast<int>(arity)); | 984 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity)); |
| 985 all[0] = callee; | 985 all[0] = callee; |
| 986 all[1] = environment()->LookupRegister(receiver); | 986 all[1] = environment()->LookupRegister(receiver); |
| 987 int receiver_index = receiver.index(); | 987 int receiver_index = receiver.index(); |
| 988 for (int i = 2; i < static_cast<int>(arity); ++i) { | 988 for (int i = 2; i < static_cast<int>(arity); ++i) { |
| 989 all[i] = environment()->LookupRegister( | 989 all[i] = environment()->LookupRegister( |
| 990 interpreter::Register(receiver_index + i - 1)); | 990 interpreter::Register(receiver_index + i - 1)); |
| 991 } | 991 } |
| 992 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); | 992 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); |
| 993 return value; | 993 return value; |
| 994 } | 994 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1030 environment()->BindAccumulator(value, &states); | 1030 environment()->BindAccumulator(value, &states); |
| 1031 } | 1031 } |
| 1032 | 1032 |
| 1033 void BytecodeGraphBuilder::VisitCallJSRuntime() { BuildCallJSRuntime(); } | 1033 void BytecodeGraphBuilder::VisitCallJSRuntime() { BuildCallJSRuntime(); } |
| 1034 | 1034 |
| 1035 void BytecodeGraphBuilder::VisitCallJSRuntimeWide() { BuildCallJSRuntime(); } | 1035 void BytecodeGraphBuilder::VisitCallJSRuntimeWide() { BuildCallJSRuntime(); } |
| 1036 | 1036 |
| 1037 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments( | 1037 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments( |
| 1038 const Operator* call_runtime_op, interpreter::Register first_arg, | 1038 const Operator* call_runtime_op, interpreter::Register first_arg, |
| 1039 size_t arity) { | 1039 size_t arity) { |
| 1040 Node** all = info()->zone()->NewArray<Node*>(arity); | 1040 Node** all = local_zone()->NewArray<Node*>(arity); |
| 1041 int first_arg_index = first_arg.index(); | 1041 int first_arg_index = first_arg.index(); |
| 1042 for (int i = 0; i < static_cast<int>(arity); ++i) { | 1042 for (int i = 0; i < static_cast<int>(arity); ++i) { |
| 1043 all[i] = environment()->LookupRegister( | 1043 all[i] = environment()->LookupRegister( |
| 1044 interpreter::Register(first_arg_index + i)); | 1044 interpreter::Register(first_arg_index + i)); |
| 1045 } | 1045 } |
| 1046 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false); | 1046 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false); |
| 1047 return value; | 1047 return value; |
| 1048 } | 1048 } |
| 1049 | 1049 |
| 1050 void BytecodeGraphBuilder::BuildCallRuntime() { | 1050 void BytecodeGraphBuilder::BuildCallRuntime() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 BuildCallRuntimeForPair(); | 1083 BuildCallRuntimeForPair(); |
| 1084 } | 1084 } |
| 1085 | 1085 |
| 1086 void BytecodeGraphBuilder::VisitCallRuntimeForPairWide() { | 1086 void BytecodeGraphBuilder::VisitCallRuntimeForPairWide() { |
| 1087 BuildCallRuntimeForPair(); | 1087 BuildCallRuntimeForPair(); |
| 1088 } | 1088 } |
| 1089 | 1089 |
| 1090 Node* BytecodeGraphBuilder::ProcessCallNewArguments( | 1090 Node* BytecodeGraphBuilder::ProcessCallNewArguments( |
| 1091 const Operator* call_new_op, Node* callee, Node* new_target, | 1091 const Operator* call_new_op, Node* callee, Node* new_target, |
| 1092 interpreter::Register first_arg, size_t arity) { | 1092 interpreter::Register first_arg, size_t arity) { |
| 1093 Node** all = info()->zone()->NewArray<Node*>(arity); | 1093 Node** all = local_zone()->NewArray<Node*>(arity); |
| 1094 all[0] = new_target; | 1094 all[0] = new_target; |
| 1095 int first_arg_index = first_arg.index(); | 1095 int first_arg_index = first_arg.index(); |
| 1096 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) { | 1096 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) { |
| 1097 all[i] = environment()->LookupRegister( | 1097 all[i] = environment()->LookupRegister( |
| 1098 interpreter::Register(first_arg_index + i - 1)); | 1098 interpreter::Register(first_arg_index + i - 1)); |
| 1099 } | 1099 } |
| 1100 all[arity - 1] = callee; | 1100 all[arity - 1] = callee; |
| 1101 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false); | 1101 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false); |
| 1102 return value; | 1102 return value; |
| 1103 } | 1103 } |
| (...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1745 // Phi does not exist yet, introduce one. | 1745 // Phi does not exist yet, introduce one. |
| 1746 value = NewPhi(inputs, value, control); | 1746 value = NewPhi(inputs, value, control); |
| 1747 value->ReplaceInput(inputs - 1, other); | 1747 value->ReplaceInput(inputs - 1, other); |
| 1748 } | 1748 } |
| 1749 return value; | 1749 return value; |
| 1750 } | 1750 } |
| 1751 | 1751 |
| 1752 } // namespace compiler | 1752 } // namespace compiler |
| 1753 } // namespace internal | 1753 } // namespace internal |
| 1754 } // namespace v8 | 1754 } // namespace v8 |
| OLD | NEW |