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 |