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/ast/ast.h" | 7 #include "src/ast/ast.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compiler/access-builder.h" | 9 #include "src/compiler/access-builder.h" |
10 #include "src/compiler/compiler-source-position-table.h" | 10 #include "src/compiler/compiler-source-position-table.h" |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 accumulator_state_value, Context(), builder()->GetFunctionClosure(), | 433 accumulator_state_value, Context(), builder()->GetFunctionClosure(), |
434 builder()->graph()->start()); | 434 builder()->graph()->start()); |
435 | 435 |
436 return result; | 436 return result; |
437 } | 437 } |
438 | 438 |
439 BytecodeGraphBuilder::BytecodeGraphBuilder( | 439 BytecodeGraphBuilder::BytecodeGraphBuilder( |
440 Zone* local_zone, Handle<SharedFunctionInfo> shared_info, | 440 Zone* local_zone, Handle<SharedFunctionInfo> shared_info, |
441 Handle<FeedbackVector> feedback_vector, BailoutId osr_ast_id, | 441 Handle<FeedbackVector> feedback_vector, BailoutId osr_ast_id, |
442 JSGraph* jsgraph, CallFrequency invocation_frequency, | 442 JSGraph* jsgraph, CallFrequency invocation_frequency, |
443 SourcePositionTable* source_positions, int inlining_id, | 443 SourcePositionTable* source_positions, Handle<Context> native_context, |
| 444 CompilationDependencies* dependencies, int inlining_id, |
444 JSTypeHintLowering::Flags flags) | 445 JSTypeHintLowering::Flags flags) |
445 : local_zone_(local_zone), | 446 : local_zone_(local_zone), |
446 jsgraph_(jsgraph), | 447 jsgraph_(jsgraph), |
447 invocation_frequency_(invocation_frequency), | 448 invocation_frequency_(invocation_frequency), |
448 bytecode_array_(handle(shared_info->bytecode_array())), | 449 bytecode_array_(handle(shared_info->bytecode_array())), |
449 exception_handler_table_( | 450 exception_handler_table_( |
450 handle(HandlerTable::cast(bytecode_array()->handler_table()))), | 451 handle(HandlerTable::cast(bytecode_array()->handler_table()))), |
451 feedback_vector_(feedback_vector), | 452 feedback_vector_(feedback_vector), |
452 type_hint_lowering_(jsgraph, feedback_vector, flags), | 453 type_hint_lowering_(jsgraph, feedback_vector, native_context, |
| 454 dependencies, flags), |
453 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 455 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
454 FrameStateType::kInterpretedFunction, | 456 FrameStateType::kInterpretedFunction, |
455 bytecode_array()->parameter_count(), | 457 bytecode_array()->parameter_count(), |
456 bytecode_array()->register_count(), shared_info)), | 458 bytecode_array()->register_count(), shared_info)), |
457 bytecode_iterator_(nullptr), | 459 bytecode_iterator_(nullptr), |
458 bytecode_analysis_(nullptr), | 460 bytecode_analysis_(nullptr), |
459 environment_(nullptr), | 461 environment_(nullptr), |
460 osr_ast_id_(osr_ast_id), | 462 osr_ast_id_(osr_ast_id), |
461 merge_environments_(local_zone), | 463 merge_environments_(local_zone), |
462 exception_handlers_(local_zone), | 464 exception_handlers_(local_zone), |
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 PrepareEagerCheckpoint(); | 1030 PrepareEagerCheckpoint(); |
1029 Node* object = | 1031 Node* object = |
1030 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1032 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1031 Handle<Name> name = | 1033 Handle<Name> name = |
1032 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1)); | 1034 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1)); |
1033 VectorSlotPair feedback = | 1035 VectorSlotPair feedback = |
1034 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2)); | 1036 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2)); |
1035 const Operator* op = javascript()->LoadNamed(name, feedback); | 1037 const Operator* op = javascript()->LoadNamed(name, feedback); |
1036 | 1038 |
1037 Node* node = nullptr; | 1039 Node* node = nullptr; |
1038 if (Node* simplified = | 1040 Environment::FrameStateAttachmentMode should_attach_frame_state; |
1039 TryBuildSimplifiedLoadNamed(op, object, feedback.slot())) { | 1041 JSTypeHintLowering::LoweringResult lowering = |
1040 if (environment() == nullptr) return; | 1042 TryBuildSimplifiedLoadNamed(op, object, feedback.slot()); |
1041 node = simplified; | 1043 if (lowering.IsSideEffectFree()) { |
| 1044 node = lowering.value(); |
| 1045 should_attach_frame_state = Environment::kDontAttachFrameState; |
| 1046 } else if (lowering.IsExit()) { |
| 1047 return; |
1042 } else { | 1048 } else { |
| 1049 DCHECK(!lowering.Changed()); |
1043 node = NewNode(op, object); | 1050 node = NewNode(op, object); |
| 1051 should_attach_frame_state = Environment::kAttachFrameState; |
1044 } | 1052 } |
1045 | 1053 environment()->BindAccumulator(node, should_attach_frame_state); |
1046 environment()->BindAccumulator(node, Environment::kAttachFrameState); | |
1047 } | 1054 } |
1048 | 1055 |
1049 void BytecodeGraphBuilder::VisitLdaKeyedProperty() { | 1056 void BytecodeGraphBuilder::VisitLdaKeyedProperty() { |
1050 PrepareEagerCheckpoint(); | 1057 PrepareEagerCheckpoint(); |
1051 Node* key = environment()->LookupAccumulator(); | 1058 Node* key = environment()->LookupAccumulator(); |
1052 Node* object = | 1059 Node* object = |
1053 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1060 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1054 VectorSlotPair feedback = | 1061 VectorSlotPair feedback = |
1055 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1)); | 1062 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1)); |
1056 const Operator* op = javascript()->LoadProperty(feedback); | 1063 const Operator* op = javascript()->LoadProperty(feedback); |
(...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2651 Reduction early_reduction = | 2658 Reduction early_reduction = |
2652 type_hint_lowering().ReduceToPrimitiveToStringOperation(value, effect, | 2659 type_hint_lowering().ReduceToPrimitiveToStringOperation(value, effect, |
2653 control, slot); | 2660 control, slot); |
2654 if (early_reduction.Changed()) { | 2661 if (early_reduction.Changed()) { |
2655 ApplyEarlyReduction(early_reduction); | 2662 ApplyEarlyReduction(early_reduction); |
2656 return early_reduction.replacement(); | 2663 return early_reduction.replacement(); |
2657 } | 2664 } |
2658 return nullptr; | 2665 return nullptr; |
2659 } | 2666 } |
2660 | 2667 |
2661 Node* BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op, | 2668 JSTypeHintLowering::LoweringResult |
2662 Node* receiver, | 2669 BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op, |
2663 FeedbackSlot slot) { | 2670 Node* receiver, |
| 2671 FeedbackSlot slot) { |
2664 // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being | 2672 // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being |
2665 // pruned from the graph by a soft-deopt. It can happen that a LoadIC that | 2673 // pruned from the graph by a soft-deopt. It can happen that a LoadIC that |
2666 // control-dominates the OSR entry is still in "uninitialized" state. | 2674 // control-dominates the OSR entry is still in "uninitialized" state. |
2667 if (bytecode_analysis()->HasOSREntryPoint()) return nullptr; | 2675 if (bytecode_analysis()->HasOSREntryPoint()) { |
| 2676 return JSTypeHintLowering::LoweringResult::NoChange(); |
| 2677 } |
2668 Node* effect = environment()->GetEffectDependency(); | 2678 Node* effect = environment()->GetEffectDependency(); |
2669 Node* control = environment()->GetControlDependency(); | 2679 Node* control = environment()->GetControlDependency(); |
2670 Reduction early_reduction = type_hint_lowering().ReduceLoadNamedOperation( | 2680 JSTypeHintLowering::LoweringResult early_reduction = |
2671 op, receiver, effect, control, slot); | 2681 type_hint_lowering().ReduceLoadNamedOperation(op, receiver, effect, |
2672 if (early_reduction.Changed()) { | 2682 control, slot); |
2673 ApplyEarlyReduction(early_reduction); | 2683 ApplyEarlyReduction(early_reduction); |
2674 return early_reduction.replacement(); | 2684 return early_reduction; |
2675 } | |
2676 return nullptr; | |
2677 } | 2685 } |
2678 | 2686 |
2679 Node* BytecodeGraphBuilder::TryBuildSimplifiedLoadKeyed(const Operator* op, | 2687 Node* BytecodeGraphBuilder::TryBuildSimplifiedLoadKeyed(const Operator* op, |
2680 Node* receiver, | 2688 Node* receiver, |
2681 Node* key, | 2689 Node* key, |
2682 FeedbackSlot slot) { | 2690 FeedbackSlot slot) { |
2683 // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being | 2691 // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being |
2684 // pruned from the graph by a soft-deopt. It can happen that a LoadIC that | 2692 // pruned from the graph by a soft-deopt. It can happen that a LoadIC that |
2685 // control-dominates the OSR entry is still in "uninitialized" state. | 2693 // control-dominates the OSR entry is still in "uninitialized" state. |
2686 if (bytecode_analysis()->HasOSREntryPoint()) return nullptr; | 2694 if (bytecode_analysis()->HasOSREntryPoint()) return nullptr; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2737 Node* node = reduction.replacement(); | 2745 Node* node = reduction.replacement(); |
2738 DCHECK(node->op()->HasProperty(Operator::kNoWrite)); | 2746 DCHECK(node->op()->HasProperty(Operator::kNoWrite)); |
2739 if (node->op()->EffectOutputCount() > 0) { | 2747 if (node->op()->EffectOutputCount() > 0) { |
2740 environment()->UpdateEffectDependency(node); | 2748 environment()->UpdateEffectDependency(node); |
2741 } | 2749 } |
2742 if (IrOpcode::IsGraphTerminator(node->opcode())) { | 2750 if (IrOpcode::IsGraphTerminator(node->opcode())) { |
2743 MergeControlToLeaveFunction(node); | 2751 MergeControlToLeaveFunction(node); |
2744 } | 2752 } |
2745 } | 2753 } |
2746 | 2754 |
| 2755 void BytecodeGraphBuilder::ApplyEarlyReduction( |
| 2756 JSTypeHintLowering::LoweringResult reduction) { |
| 2757 if (reduction.IsExit()) { |
| 2758 MergeControlToLeaveFunction(reduction.control()); |
| 2759 } else if (reduction.IsSideEffectFree()) { |
| 2760 environment()->UpdateEffectDependency(reduction.effect()); |
| 2761 environment()->UpdateControlDependency(reduction.control()); |
| 2762 } else { |
| 2763 DCHECK(!reduction.Changed()); |
| 2764 // At the moment, we assume side-effect free reduction. To support |
| 2765 // side-effects, we would have to invalidate the eager frame state, |
| 2766 // so that deoptimization does not repeat the side effect. |
| 2767 // Also note that the early reductions do not support lazy deoptimization. |
| 2768 } |
| 2769 } |
| 2770 |
2747 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) { | 2771 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) { |
2748 if (size > input_buffer_size_) { | 2772 if (size > input_buffer_size_) { |
2749 size = size + kInputBufferSizeIncrement + input_buffer_size_; | 2773 size = size + kInputBufferSizeIncrement + input_buffer_size_; |
2750 input_buffer_ = local_zone()->NewArray<Node*>(size); | 2774 input_buffer_ = local_zone()->NewArray<Node*>(size); |
2751 input_buffer_size_ = size; | 2775 input_buffer_size_ = size; |
2752 } | 2776 } |
2753 return input_buffer_; | 2777 return input_buffer_; |
2754 } | 2778 } |
2755 | 2779 |
2756 void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) { | 2780 void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) { |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2944 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2968 it->source_position().ScriptOffset(), start_position_.InliningId())); |
2945 it->Advance(); | 2969 it->Advance(); |
2946 } else { | 2970 } else { |
2947 DCHECK_GT(it->code_offset(), offset); | 2971 DCHECK_GT(it->code_offset(), offset); |
2948 } | 2972 } |
2949 } | 2973 } |
2950 | 2974 |
2951 } // namespace compiler | 2975 } // namespace compiler |
2952 } // namespace internal | 2976 } // namespace internal |
2953 } // namespace v8 | 2977 } // namespace v8 |
OLD | NEW |