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 |