| 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 |