| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/compiler/ast-loop-assignment-analyzer.h" | 9 #include "src/compiler/ast-loop-assignment-analyzer.h" |
| 10 #include "src/compiler/control-builders.h" | 10 #include "src/compiler/control-builders.h" |
| 11 #include "src/compiler/linkage.h" | 11 #include "src/compiler/linkage.h" |
| 12 #include "src/compiler/liveness-analyzer.h" | 12 #include "src/compiler/liveness-analyzer.h" |
| 13 #include "src/compiler/machine-operator.h" | 13 #include "src/compiler/machine-operator.h" |
| 14 #include "src/compiler/node-matchers.h" | 14 #include "src/compiler/node-matchers.h" |
| 15 #include "src/compiler/node-properties.h" | 15 #include "src/compiler/node-properties.h" |
| 16 #include "src/compiler/operator-properties.h" | 16 #include "src/compiler/operator-properties.h" |
| 17 #include "src/compiler/state-values-utils.h" | 17 #include "src/compiler/state-values-utils.h" |
| 18 #include "src/compiler/type-hint-analyzer.h" |
| 18 #include "src/parsing/parser.h" | 19 #include "src/parsing/parser.h" |
| 19 | 20 |
| 20 namespace v8 { | 21 namespace v8 { |
| 21 namespace internal { | 22 namespace internal { |
| 22 namespace compiler { | 23 namespace compiler { |
| 23 | 24 |
| 24 | 25 |
| 25 // Each expression in the AST is evaluated in a specific context. This context | 26 // Each expression in the AST is evaluated in a specific context. This context |
| 26 // decides how the evaluation result is passed up the visitor. | 27 // decides how the evaluation result is passed up the visitor. |
| 27 class AstGraphBuilder::AstContext BASE_EMBEDDED { | 28 class AstGraphBuilder::AstContext BASE_EMBEDDED { |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 } | 422 } |
| 422 } | 423 } |
| 423 | 424 |
| 424 private: | 425 private: |
| 425 AstGraphBuilder* builder_; | 426 AstGraphBuilder* builder_; |
| 426 Node* frame_state_before_; | 427 Node* frame_state_before_; |
| 427 }; | 428 }; |
| 428 | 429 |
| 429 | 430 |
| 430 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, | 431 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, |
| 431 JSGraph* jsgraph, LoopAssignmentAnalysis* loop) | 432 JSGraph* jsgraph, LoopAssignmentAnalysis* loop, |
| 433 TypeHintAnalysis* type_hint_analysis) |
| 432 : isolate_(info->isolate()), | 434 : isolate_(info->isolate()), |
| 433 local_zone_(local_zone), | 435 local_zone_(local_zone), |
| 434 info_(info), | 436 info_(info), |
| 435 jsgraph_(jsgraph), | 437 jsgraph_(jsgraph), |
| 436 environment_(nullptr), | 438 environment_(nullptr), |
| 437 ast_context_(nullptr), | 439 ast_context_(nullptr), |
| 438 globals_(0, local_zone), | 440 globals_(0, local_zone), |
| 439 execution_control_(nullptr), | 441 execution_control_(nullptr), |
| 440 execution_context_(nullptr), | 442 execution_context_(nullptr), |
| 441 try_catch_nesting_level_(0), | 443 try_catch_nesting_level_(0), |
| 442 try_nesting_level_(0), | 444 try_nesting_level_(0), |
| 443 input_buffer_size_(0), | 445 input_buffer_size_(0), |
| 444 input_buffer_(nullptr), | 446 input_buffer_(nullptr), |
| 445 exit_controls_(local_zone), | 447 exit_controls_(local_zone), |
| 446 loop_assignment_analysis_(loop), | 448 loop_assignment_analysis_(loop), |
| 449 type_hint_analysis_(type_hint_analysis), |
| 447 state_values_cache_(jsgraph), | 450 state_values_cache_(jsgraph), |
| 448 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), | 451 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), |
| 449 local_zone), | 452 local_zone), |
| 450 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 453 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
| 451 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, | 454 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, |
| 452 info->scope()->num_stack_slots(), info->shared_info(), | 455 info->scope()->num_stack_slots(), info->shared_info(), |
| 453 CALL_MAINTAINS_NATIVE_CONTEXT)) { | 456 CALL_MAINTAINS_NATIVE_CONTEXT)) { |
| 454 InitializeAstVisitor(info->isolate()); | 457 InitializeAstVisitor(info->isolate()); |
| 455 } | 458 } |
| 456 | 459 |
| (...skipping 1702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2159 break; | 2162 break; |
| 2160 } | 2163 } |
| 2161 } | 2164 } |
| 2162 environment()->Push(old_value); | 2165 environment()->Push(old_value); |
| 2163 VisitForValue(expr->value()); | 2166 VisitForValue(expr->value()); |
| 2164 Node* value; | 2167 Node* value; |
| 2165 { | 2168 { |
| 2166 FrameStateBeforeAndAfter states(this, expr->value()->id()); | 2169 FrameStateBeforeAndAfter states(this, expr->value()->id()); |
| 2167 Node* right = environment()->Pop(); | 2170 Node* right = environment()->Pop(); |
| 2168 Node* left = environment()->Pop(); | 2171 Node* left = environment()->Pop(); |
| 2169 value = BuildBinaryOp(left, right, expr->binary_op()); | 2172 value = |
| 2173 BuildBinaryOp(left, right, expr->binary_op(), |
| 2174 expr->binary_operation()->BinaryOperationFeedbackId()); |
| 2170 states.AddToNode(value, expr->binary_operation()->id(), | 2175 states.AddToNode(value, expr->binary_operation()->id(), |
| 2171 OutputFrameStateCombine::Push()); | 2176 OutputFrameStateCombine::Push()); |
| 2172 } | 2177 } |
| 2173 environment()->Push(value); | 2178 environment()->Push(value); |
| 2174 if (needs_frame_state_before) { | 2179 if (needs_frame_state_before) { |
| 2175 before_store_id = expr->binary_operation()->id(); | 2180 before_store_id = expr->binary_operation()->id(); |
| 2176 } | 2181 } |
| 2177 } else { | 2182 } else { |
| 2178 VisitForValue(expr->value()); | 2183 VisitForValue(expr->value()); |
| 2179 if (needs_frame_state_before) { | 2184 if (needs_frame_state_before) { |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2718 if (assign_type != VARIABLE) { | 2723 if (assign_type != VARIABLE) { |
| 2719 environment()->Poke(stack_depth, old_value); | 2724 environment()->Poke(stack_depth, old_value); |
| 2720 } else { | 2725 } else { |
| 2721 environment()->Push(old_value); | 2726 environment()->Push(old_value); |
| 2722 } | 2727 } |
| 2723 } | 2728 } |
| 2724 | 2729 |
| 2725 // Create node to perform +1/-1 operation. | 2730 // Create node to perform +1/-1 operation. |
| 2726 Node* value; | 2731 Node* value; |
| 2727 { | 2732 { |
| 2733 // TODO(bmeurer): Cleanup this feedback/bailout mess! |
| 2728 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 2734 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
| 2729 value = | 2735 value = BuildBinaryOp(old_value, jsgraph()->OneConstant(), |
| 2730 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); | 2736 expr->binary_op(), TypeFeedbackId::None()); |
| 2731 // This should never deoptimize outside strong mode because otherwise we | 2737 // This should never deoptimize outside strong mode because otherwise we |
| 2732 // have converted to number before. | 2738 // have converted to number before. |
| 2733 states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId() | 2739 states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId() |
| 2734 : BailoutId::None(), | 2740 : BailoutId::None(), |
| 2735 OutputFrameStateCombine::Ignore()); | 2741 OutputFrameStateCombine::Ignore()); |
| 2736 } | 2742 } |
| 2737 | 2743 |
| 2738 // Store the value. | 2744 // Store the value. |
| 2739 VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot()); | 2745 VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot()); |
| 2740 switch (assign_type) { | 2746 switch (assign_type) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2803 return VisitComma(expr); | 2809 return VisitComma(expr); |
| 2804 case Token::OR: | 2810 case Token::OR: |
| 2805 case Token::AND: | 2811 case Token::AND: |
| 2806 return VisitLogicalExpression(expr); | 2812 return VisitLogicalExpression(expr); |
| 2807 default: { | 2813 default: { |
| 2808 VisitForValue(expr->left()); | 2814 VisitForValue(expr->left()); |
| 2809 VisitForValue(expr->right()); | 2815 VisitForValue(expr->right()); |
| 2810 FrameStateBeforeAndAfter states(this, expr->right()->id()); | 2816 FrameStateBeforeAndAfter states(this, expr->right()->id()); |
| 2811 Node* right = environment()->Pop(); | 2817 Node* right = environment()->Pop(); |
| 2812 Node* left = environment()->Pop(); | 2818 Node* left = environment()->Pop(); |
| 2813 Node* value = BuildBinaryOp(left, right, expr->op()); | 2819 Node* value = BuildBinaryOp(left, right, expr->op(), |
| 2820 expr->BinaryOperationFeedbackId()); |
| 2814 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2821 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
| 2815 ast_context()->ProduceValue(value); | 2822 ast_context()->ProduceValue(value); |
| 2816 } | 2823 } |
| 2817 } | 2824 } |
| 2818 } | 2825 } |
| 2819 | 2826 |
| 2820 | 2827 |
| 2821 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 2828 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
| 2822 const Operator* op; | 2829 const Operator* op; |
| 2823 switch (expr->op()) { | 2830 switch (expr->op()) { |
| (...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3774 | 3781 |
| 3775 | 3782 |
| 3776 Node* AstGraphBuilder::BuildThrow(Node* exception_value) { | 3783 Node* AstGraphBuilder::BuildThrow(Node* exception_value) { |
| 3777 NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value); | 3784 NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value); |
| 3778 Node* control = NewNode(common()->Throw(), exception_value); | 3785 Node* control = NewNode(common()->Throw(), exception_value); |
| 3779 UpdateControlDependencyToLeaveFunction(control); | 3786 UpdateControlDependencyToLeaveFunction(control); |
| 3780 return control; | 3787 return control; |
| 3781 } | 3788 } |
| 3782 | 3789 |
| 3783 | 3790 |
| 3784 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) { | 3791 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op, |
| 3792 TypeFeedbackId feedback_id) { |
| 3785 const Operator* js_op; | 3793 const Operator* js_op; |
| 3794 BinaryOperationHints hints; |
| 3795 if (!type_hint_analysis_ || |
| 3796 !type_hint_analysis_->GetBinaryOperationHints(feedback_id, &hints)) { |
| 3797 hints = BinaryOperationHints::Any(); |
| 3798 } |
| 3786 switch (op) { | 3799 switch (op) { |
| 3787 case Token::BIT_OR: | 3800 case Token::BIT_OR: |
| 3788 js_op = javascript()->BitwiseOr(language_mode()); | 3801 js_op = javascript()->BitwiseOr(language_mode(), hints); |
| 3789 break; | 3802 break; |
| 3790 case Token::BIT_AND: | 3803 case Token::BIT_AND: |
| 3791 js_op = javascript()->BitwiseAnd(language_mode()); | 3804 js_op = javascript()->BitwiseAnd(language_mode(), hints); |
| 3792 break; | 3805 break; |
| 3793 case Token::BIT_XOR: | 3806 case Token::BIT_XOR: |
| 3794 js_op = javascript()->BitwiseXor(language_mode()); | 3807 js_op = javascript()->BitwiseXor(language_mode(), hints); |
| 3795 break; | 3808 break; |
| 3796 case Token::SHL: | 3809 case Token::SHL: |
| 3797 js_op = javascript()->ShiftLeft(language_mode()); | 3810 js_op = javascript()->ShiftLeft(language_mode(), hints); |
| 3798 break; | 3811 break; |
| 3799 case Token::SAR: | 3812 case Token::SAR: |
| 3800 js_op = javascript()->ShiftRight(language_mode()); | 3813 js_op = javascript()->ShiftRight(language_mode(), hints); |
| 3801 break; | 3814 break; |
| 3802 case Token::SHR: | 3815 case Token::SHR: |
| 3803 js_op = javascript()->ShiftRightLogical(language_mode()); | 3816 js_op = javascript()->ShiftRightLogical(language_mode(), hints); |
| 3804 break; | 3817 break; |
| 3805 case Token::ADD: | 3818 case Token::ADD: |
| 3806 js_op = javascript()->Add(language_mode()); | 3819 js_op = javascript()->Add(language_mode(), hints); |
| 3807 break; | 3820 break; |
| 3808 case Token::SUB: | 3821 case Token::SUB: |
| 3809 js_op = javascript()->Subtract(language_mode()); | 3822 js_op = javascript()->Subtract(language_mode(), hints); |
| 3810 break; | 3823 break; |
| 3811 case Token::MUL: | 3824 case Token::MUL: |
| 3812 js_op = javascript()->Multiply(language_mode()); | 3825 js_op = javascript()->Multiply(language_mode(), hints); |
| 3813 break; | 3826 break; |
| 3814 case Token::DIV: | 3827 case Token::DIV: |
| 3815 js_op = javascript()->Divide(language_mode()); | 3828 js_op = javascript()->Divide(language_mode(), hints); |
| 3816 break; | 3829 break; |
| 3817 case Token::MOD: | 3830 case Token::MOD: |
| 3818 js_op = javascript()->Modulus(language_mode()); | 3831 js_op = javascript()->Modulus(language_mode(), hints); |
| 3819 break; | 3832 break; |
| 3820 default: | 3833 default: |
| 3821 UNREACHABLE(); | 3834 UNREACHABLE(); |
| 3822 js_op = NULL; | 3835 js_op = NULL; |
| 3823 } | 3836 } |
| 3824 return NewNode(js_op, left, right); | 3837 return NewNode(js_op, left, right); |
| 3825 } | 3838 } |
| 3826 | 3839 |
| 3827 | 3840 |
| 3828 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { | 3841 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4304 // Phi does not exist yet, introduce one. | 4317 // Phi does not exist yet, introduce one. |
| 4305 value = NewPhi(inputs, value, control); | 4318 value = NewPhi(inputs, value, control); |
| 4306 value->ReplaceInput(inputs - 1, other); | 4319 value->ReplaceInput(inputs - 1, other); |
| 4307 } | 4320 } |
| 4308 return value; | 4321 return value; |
| 4309 } | 4322 } |
| 4310 | 4323 |
| 4311 } // namespace compiler | 4324 } // namespace compiler |
| 4312 } // namespace internal | 4325 } // namespace internal |
| 4313 } // namespace v8 | 4326 } // namespace v8 |
| OLD | NEW |