| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 | 31 |
| 32 #include "v8.h" | 32 #include "v8.h" |
| 33 #include "codegen.h" | 33 #include "codegen.h" |
| 34 #include "full-codegen.h" | 34 #include "full-codegen.h" |
| 35 #include "hashmap.h" | 35 #include "hashmap.h" |
| 36 #include "lithium-allocator.h" | 36 #include "lithium-allocator.h" |
| 37 #include "parser.h" | 37 #include "parser.h" |
| 38 #include "scopeinfo.h" | 38 #include "scopeinfo.h" |
| 39 #include "scopes.h" | 39 #include "scopes.h" |
| 40 #include "stub-cache.h" | 40 #include "stub-cache.h" |
| 41 #include "typing.h" |
| 41 | 42 |
| 42 #if V8_TARGET_ARCH_IA32 | 43 #if V8_TARGET_ARCH_IA32 |
| 43 #include "ia32/lithium-codegen-ia32.h" | 44 #include "ia32/lithium-codegen-ia32.h" |
| 44 #elif V8_TARGET_ARCH_X64 | 45 #elif V8_TARGET_ARCH_X64 |
| 45 #include "x64/lithium-codegen-x64.h" | 46 #include "x64/lithium-codegen-x64.h" |
| 46 #elif V8_TARGET_ARCH_ARM | 47 #elif V8_TARGET_ARCH_ARM |
| 47 #include "arm/lithium-codegen-arm.h" | 48 #include "arm/lithium-codegen-arm.h" |
| 48 #elif V8_TARGET_ARCH_MIPS | 49 #elif V8_TARGET_ARCH_MIPS |
| 49 #include "mips/lithium-codegen-mips.h" | 50 #include "mips/lithium-codegen-mips.h" |
| 50 #else | 51 #else |
| (...skipping 1962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2013 | 2014 |
| 2014 if (fill_with_hole) { | 2015 if (fill_with_hole) { |
| 2015 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, | 2016 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, |
| 2016 graph()->GetConstant0(), capacity); | 2017 graph()->GetConstant0(), capacity); |
| 2017 } | 2018 } |
| 2018 | 2019 |
| 2019 return new_object; | 2020 return new_object; |
| 2020 } | 2021 } |
| 2021 | 2022 |
| 2022 | 2023 |
| 2023 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 2024 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) |
| 2024 TypeFeedbackOracle* oracle) | |
| 2025 : HGraphBuilder(info), | 2025 : HGraphBuilder(info), |
| 2026 function_state_(NULL), | 2026 function_state_(NULL), |
| 2027 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 2027 initial_function_state_(this, info, NORMAL_RETURN), |
| 2028 ast_context_(NULL), | 2028 ast_context_(NULL), |
| 2029 break_scope_(NULL), | 2029 break_scope_(NULL), |
| 2030 inlined_count_(0), | 2030 inlined_count_(0), |
| 2031 globals_(10, info->zone()), | 2031 globals_(10, info->zone()), |
| 2032 inline_bailout_(false) { | 2032 inline_bailout_(false) { |
| 2033 // This is not initialized in the initializer list because the | 2033 // This is not initialized in the initializer list because the |
| 2034 // constructor for the initial state relies on function_state_ == NULL | 2034 // constructor for the initial state relies on function_state_ == NULL |
| 2035 // to know it's the initial state. | 2035 // to know it's the initial state. |
| 2036 function_state_= &initial_function_state_; | 2036 function_state_= &initial_function_state_; |
| 2037 InitializeAstVisitor(); | 2037 InitializeAstVisitor(); |
| (...skipping 2369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4407 } | 4407 } |
| 4408 } | 4408 } |
| 4409 } | 4409 } |
| 4410 } | 4410 } |
| 4411 | 4411 |
| 4412 | 4412 |
| 4413 // Implementation of utility class to encapsulate the translation state for | 4413 // Implementation of utility class to encapsulate the translation state for |
| 4414 // a (possibly inlined) function. | 4414 // a (possibly inlined) function. |
| 4415 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, | 4415 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, |
| 4416 CompilationInfo* info, | 4416 CompilationInfo* info, |
| 4417 TypeFeedbackOracle* oracle, | |
| 4418 InliningKind inlining_kind) | 4417 InliningKind inlining_kind) |
| 4419 : owner_(owner), | 4418 : owner_(owner), |
| 4420 compilation_info_(info), | 4419 compilation_info_(info), |
| 4421 oracle_(oracle), | |
| 4422 call_context_(NULL), | 4420 call_context_(NULL), |
| 4423 inlining_kind_(inlining_kind), | 4421 inlining_kind_(inlining_kind), |
| 4424 function_return_(NULL), | 4422 function_return_(NULL), |
| 4425 test_context_(NULL), | 4423 test_context_(NULL), |
| 4426 entry_(NULL), | 4424 entry_(NULL), |
| 4427 arguments_elements_(NULL), | 4425 arguments_elements_(NULL), |
| 4428 outer_(owner->function_state()) { | 4426 outer_(owner->function_state()) { |
| 4429 if (outer_ != NULL) { | 4427 if (outer_ != NULL) { |
| 4430 // State for an inline function. | 4428 // State for an inline function. |
| 4431 if (owner->ast_context()->IsTest()) { | 4429 if (owner->ast_context()->IsTest()) { |
| 4432 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); | 4430 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); |
| 4433 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); | 4431 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); |
| 4434 if_true->MarkAsInlineReturnTarget(); | 4432 if_true->MarkAsInlineReturnTarget(); |
| 4435 if_false->MarkAsInlineReturnTarget(); | 4433 if_false->MarkAsInlineReturnTarget(); |
| 4436 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); | 4434 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); |
| 4437 Expression* cond = outer_test_context->condition(); | 4435 Expression* cond = outer_test_context->condition(); |
| 4438 TypeFeedbackOracle* outer_oracle = outer_test_context->oracle(); | |
| 4439 // The AstContext constructor pushed on the context stack. This newed | 4436 // The AstContext constructor pushed on the context stack. This newed |
| 4440 // instance is the reason that AstContext can't be BASE_EMBEDDED. | 4437 // instance is the reason that AstContext can't be BASE_EMBEDDED. |
| 4441 test_context_ = | 4438 test_context_ = new TestContext(owner, cond, if_true, if_false); |
| 4442 new TestContext(owner, cond, outer_oracle, if_true, if_false); | |
| 4443 } else { | 4439 } else { |
| 4444 function_return_ = owner->graph()->CreateBasicBlock(); | 4440 function_return_ = owner->graph()->CreateBasicBlock(); |
| 4445 function_return()->MarkAsInlineReturnTarget(); | 4441 function_return()->MarkAsInlineReturnTarget(); |
| 4446 } | 4442 } |
| 4447 // Set this after possibly allocating a new TestContext above. | 4443 // Set this after possibly allocating a new TestContext above. |
| 4448 call_context_ = owner->ast_context(); | 4444 call_context_ = owner->ast_context(); |
| 4449 } | 4445 } |
| 4450 | 4446 |
| 4451 // Push on the state stack. | 4447 // Push on the state stack. |
| 4452 owner->set_function_state(this); | 4448 owner->set_function_state(this); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4666 if (constant_value->BooleanValue()) { | 4662 if (constant_value->BooleanValue()) { |
| 4667 builder->current_block()->Goto(if_true(), builder->function_state()); | 4663 builder->current_block()->Goto(if_true(), builder->function_state()); |
| 4668 } else { | 4664 } else { |
| 4669 builder->current_block()->Goto(if_false(), builder->function_state()); | 4665 builder->current_block()->Goto(if_false(), builder->function_state()); |
| 4670 } | 4666 } |
| 4671 builder->set_current_block(NULL); | 4667 builder->set_current_block(NULL); |
| 4672 return; | 4668 return; |
| 4673 } | 4669 } |
| 4674 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); | 4670 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); |
| 4675 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); | 4671 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); |
| 4676 TypeFeedbackId test_id = condition()->test_id(); | 4672 ToBooleanStub::Types expected(condition()->to_boolean_types()); |
| 4677 ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id)); | |
| 4678 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); | 4673 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); |
| 4679 builder->current_block()->Finish(test); | 4674 builder->current_block()->Finish(test); |
| 4680 | 4675 |
| 4681 empty_true->Goto(if_true(), builder->function_state()); | 4676 empty_true->Goto(if_true(), builder->function_state()); |
| 4682 empty_false->Goto(if_false(), builder->function_state()); | 4677 empty_false->Goto(if_false(), builder->function_state()); |
| 4683 builder->set_current_block(NULL); | 4678 builder->set_current_block(NULL); |
| 4684 } | 4679 } |
| 4685 | 4680 |
| 4686 | 4681 |
| 4687 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. | 4682 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4722 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); | 4717 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); |
| 4723 for_value.set_for_typeof(true); | 4718 for_value.set_for_typeof(true); |
| 4724 Visit(expr); | 4719 Visit(expr); |
| 4725 } | 4720 } |
| 4726 | 4721 |
| 4727 | 4722 |
| 4728 | 4723 |
| 4729 void HOptimizedGraphBuilder::VisitForControl(Expression* expr, | 4724 void HOptimizedGraphBuilder::VisitForControl(Expression* expr, |
| 4730 HBasicBlock* true_block, | 4725 HBasicBlock* true_block, |
| 4731 HBasicBlock* false_block) { | 4726 HBasicBlock* false_block) { |
| 4732 TestContext for_test(this, expr, oracle(), true_block, false_block); | 4727 TestContext for_test(this, expr, true_block, false_block); |
| 4733 Visit(expr); | 4728 Visit(expr); |
| 4734 } | 4729 } |
| 4735 | 4730 |
| 4736 | 4731 |
| 4737 void HOptimizedGraphBuilder::VisitArgument(Expression* expr) { | 4732 void HOptimizedGraphBuilder::VisitArgument(Expression* expr) { |
| 4738 CHECK_ALIVE(VisitForValue(expr)); | 4733 CHECK_ALIVE(VisitForValue(expr)); |
| 4739 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); | 4734 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); |
| 4740 } | 4735 } |
| 4741 | 4736 |
| 4742 | 4737 |
| (...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5729 return block; | 5724 return block; |
| 5730 } | 5725 } |
| 5731 | 5726 |
| 5732 | 5727 |
| 5733 void HOptimizedGraphBuilder::VisitContinueStatement( | 5728 void HOptimizedGraphBuilder::VisitContinueStatement( |
| 5734 ContinueStatement* stmt) { | 5729 ContinueStatement* stmt) { |
| 5735 ASSERT(!HasStackOverflow()); | 5730 ASSERT(!HasStackOverflow()); |
| 5736 ASSERT(current_block() != NULL); | 5731 ASSERT(current_block() != NULL); |
| 5737 ASSERT(current_block()->HasPredecessor()); | 5732 ASSERT(current_block()->HasPredecessor()); |
| 5738 int drop_extra = 0; | 5733 int drop_extra = 0; |
| 5739 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), | 5734 HBasicBlock* continue_block = break_scope()->Get( |
| 5740 CONTINUE, | 5735 stmt->target(), BreakAndContinueScope::CONTINUE, &drop_extra); |
| 5741 &drop_extra); | |
| 5742 Drop(drop_extra); | 5736 Drop(drop_extra); |
| 5743 current_block()->Goto(continue_block); | 5737 current_block()->Goto(continue_block); |
| 5744 set_current_block(NULL); | 5738 set_current_block(NULL); |
| 5745 } | 5739 } |
| 5746 | 5740 |
| 5747 | 5741 |
| 5748 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { | 5742 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { |
| 5749 ASSERT(!HasStackOverflow()); | 5743 ASSERT(!HasStackOverflow()); |
| 5750 ASSERT(current_block() != NULL); | 5744 ASSERT(current_block() != NULL); |
| 5751 ASSERT(current_block()->HasPredecessor()); | 5745 ASSERT(current_block()->HasPredecessor()); |
| 5752 int drop_extra = 0; | 5746 int drop_extra = 0; |
| 5753 HBasicBlock* break_block = break_scope()->Get(stmt->target(), | 5747 HBasicBlock* break_block = break_scope()->Get( |
| 5754 BREAK, | 5748 stmt->target(), BreakAndContinueScope::BREAK, &drop_extra); |
| 5755 &drop_extra); | |
| 5756 Drop(drop_extra); | 5749 Drop(drop_extra); |
| 5757 current_block()->Goto(break_block); | 5750 current_block()->Goto(break_block); |
| 5758 set_current_block(NULL); | 5751 set_current_block(NULL); |
| 5759 } | 5752 } |
| 5760 | 5753 |
| 5761 | 5754 |
| 5762 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { | 5755 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { |
| 5763 ASSERT(!HasStackOverflow()); | 5756 ASSERT(!HasStackOverflow()); |
| 5764 ASSERT(current_block() != NULL); | 5757 ASSERT(current_block() != NULL); |
| 5765 ASSERT(current_block()->HasPredecessor()); | 5758 ASSERT(current_block()->HasPredecessor()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5836 ASSERT(current_block() != NULL); | 5829 ASSERT(current_block() != NULL); |
| 5837 ASSERT(current_block()->HasPredecessor()); | 5830 ASSERT(current_block()->HasPredecessor()); |
| 5838 return Bailout("WithStatement"); | 5831 return Bailout("WithStatement"); |
| 5839 } | 5832 } |
| 5840 | 5833 |
| 5841 | 5834 |
| 5842 void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { | 5835 void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { |
| 5843 ASSERT(!HasStackOverflow()); | 5836 ASSERT(!HasStackOverflow()); |
| 5844 ASSERT(current_block() != NULL); | 5837 ASSERT(current_block() != NULL); |
| 5845 ASSERT(current_block()->HasPredecessor()); | 5838 ASSERT(current_block()->HasPredecessor()); |
| 5839 |
| 5846 // We only optimize switch statements with smi-literal smi comparisons, | 5840 // We only optimize switch statements with smi-literal smi comparisons, |
| 5847 // with a bounded number of clauses. | 5841 // with a bounded number of clauses. |
| 5848 const int kCaseClauseLimit = 128; | 5842 const int kCaseClauseLimit = 128; |
| 5849 ZoneList<CaseClause*>* clauses = stmt->cases(); | 5843 ZoneList<CaseClause*>* clauses = stmt->cases(); |
| 5850 int clause_count = clauses->length(); | 5844 int clause_count = clauses->length(); |
| 5851 if (clause_count > kCaseClauseLimit) { | 5845 if (clause_count > kCaseClauseLimit) { |
| 5852 return Bailout("SwitchStatement: too many clauses"); | 5846 return Bailout("SwitchStatement: too many clauses"); |
| 5853 } | 5847 } |
| 5854 | 5848 |
| 5849 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); |
| 5850 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { |
| 5851 return Bailout("SwitchStatement: mixed or non-literal switch labels"); |
| 5852 } |
| 5853 |
| 5855 HValue* context = environment()->LookupContext(); | 5854 HValue* context = environment()->LookupContext(); |
| 5856 | 5855 |
| 5857 CHECK_ALIVE(VisitForValue(stmt->tag())); | 5856 CHECK_ALIVE(VisitForValue(stmt->tag())); |
| 5858 AddSimulate(stmt->EntryId()); | 5857 AddSimulate(stmt->EntryId()); |
| 5859 HValue* tag_value = Pop(); | 5858 HValue* tag_value = Pop(); |
| 5860 HBasicBlock* first_test_block = current_block(); | 5859 HBasicBlock* first_test_block = current_block(); |
| 5861 | 5860 |
| 5862 SwitchType switch_type = UNKNOWN_SWITCH; | |
| 5863 | |
| 5864 // 1. Extract clause type | |
| 5865 for (int i = 0; i < clause_count; ++i) { | |
| 5866 CaseClause* clause = clauses->at(i); | |
| 5867 if (clause->is_default()) continue; | |
| 5868 | |
| 5869 if (switch_type == UNKNOWN_SWITCH) { | |
| 5870 if (clause->label()->IsSmiLiteral()) { | |
| 5871 switch_type = SMI_SWITCH; | |
| 5872 } else if (clause->label()->IsStringLiteral()) { | |
| 5873 switch_type = STRING_SWITCH; | |
| 5874 } else { | |
| 5875 return Bailout("SwitchStatement: non-literal switch label"); | |
| 5876 } | |
| 5877 } else if ((switch_type == STRING_SWITCH && | |
| 5878 !clause->label()->IsStringLiteral()) || | |
| 5879 (switch_type == SMI_SWITCH && | |
| 5880 !clause->label()->IsSmiLiteral())) { | |
| 5881 return Bailout("SwitchStatement: mixed label types are not supported"); | |
| 5882 } | |
| 5883 } | |
| 5884 | |
| 5885 HUnaryControlInstruction* string_check = NULL; | 5861 HUnaryControlInstruction* string_check = NULL; |
| 5886 HBasicBlock* not_string_block = NULL; | 5862 HBasicBlock* not_string_block = NULL; |
| 5887 | 5863 |
| 5888 // Test switch's tag value if all clauses are string literals | 5864 // Test switch's tag value if all clauses are string literals |
| 5889 if (switch_type == STRING_SWITCH) { | 5865 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { |
| 5890 string_check = new(zone()) HIsStringAndBranch(tag_value); | 5866 string_check = new(zone()) HIsStringAndBranch(tag_value); |
| 5891 first_test_block = graph()->CreateBasicBlock(); | 5867 first_test_block = graph()->CreateBasicBlock(); |
| 5892 not_string_block = graph()->CreateBasicBlock(); | 5868 not_string_block = graph()->CreateBasicBlock(); |
| 5893 | 5869 |
| 5894 string_check->SetSuccessorAt(0, first_test_block); | 5870 string_check->SetSuccessorAt(0, first_test_block); |
| 5895 string_check->SetSuccessorAt(1, not_string_block); | 5871 string_check->SetSuccessorAt(1, not_string_block); |
| 5896 current_block()->Finish(string_check); | 5872 current_block()->Finish(string_check); |
| 5897 | 5873 |
| 5898 set_current_block(first_test_block); | 5874 set_current_block(first_test_block); |
| 5899 } | 5875 } |
| 5900 | 5876 |
| 5901 // 2. Build all the tests, with dangling true branches | 5877 // 1. Build all the tests, with dangling true branches |
| 5902 BailoutId default_id = BailoutId::None(); | 5878 BailoutId default_id = BailoutId::None(); |
| 5903 for (int i = 0; i < clause_count; ++i) { | 5879 for (int i = 0; i < clause_count; ++i) { |
| 5904 CaseClause* clause = clauses->at(i); | 5880 CaseClause* clause = clauses->at(i); |
| 5905 if (clause->is_default()) { | 5881 if (clause->is_default()) { |
| 5906 default_id = clause->EntryId(); | 5882 default_id = clause->EntryId(); |
| 5907 continue; | 5883 continue; |
| 5908 } | 5884 } |
| 5909 if (switch_type == SMI_SWITCH) { | |
| 5910 clause->RecordTypeFeedback(oracle()); | |
| 5911 } | |
| 5912 | 5885 |
| 5913 // Generate a compare and branch. | 5886 // Generate a compare and branch. |
| 5914 CHECK_ALIVE(VisitForValue(clause->label())); | 5887 CHECK_ALIVE(VisitForValue(clause->label())); |
| 5915 HValue* label_value = Pop(); | 5888 HValue* label_value = Pop(); |
| 5916 | 5889 |
| 5917 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 5890 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
| 5918 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 5891 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
| 5919 | 5892 |
| 5920 HControlInstruction* compare; | 5893 HControlInstruction* compare; |
| 5921 | 5894 |
| 5922 if (switch_type == SMI_SWITCH) { | 5895 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { |
| 5923 if (!clause->IsSmiCompare()) { | 5896 if (!clause->IsSmiCompare()) { |
| 5924 // Finish with deoptimize and add uses of enviroment values to | 5897 // Finish with deoptimize and add uses of enviroment values to |
| 5925 // account for invisible uses. | 5898 // account for invisible uses. |
| 5926 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); | 5899 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
| 5927 set_current_block(NULL); | 5900 set_current_block(NULL); |
| 5928 break; | 5901 break; |
| 5929 } | 5902 } |
| 5930 | 5903 |
| 5931 HCompareIDAndBranch* compare_ = | 5904 HCompareIDAndBranch* compare_ = |
| 5932 new(zone()) HCompareIDAndBranch(tag_value, | 5905 new(zone()) HCompareIDAndBranch(tag_value, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 5950 | 5923 |
| 5951 // Save the current block to use for the default or to join with the | 5924 // Save the current block to use for the default or to join with the |
| 5952 // exit. This block is NULL if we deoptimized. | 5925 // exit. This block is NULL if we deoptimized. |
| 5953 HBasicBlock* last_block = current_block(); | 5926 HBasicBlock* last_block = current_block(); |
| 5954 | 5927 |
| 5955 if (not_string_block != NULL) { | 5928 if (not_string_block != NULL) { |
| 5956 BailoutId join_id = !default_id.IsNone() ? default_id : stmt->ExitId(); | 5929 BailoutId join_id = !default_id.IsNone() ? default_id : stmt->ExitId(); |
| 5957 last_block = CreateJoin(last_block, not_string_block, join_id); | 5930 last_block = CreateJoin(last_block, not_string_block, join_id); |
| 5958 } | 5931 } |
| 5959 | 5932 |
| 5960 // 3. Loop over the clauses and the linked list of tests in lockstep, | 5933 // 2. Loop over the clauses and the linked list of tests in lockstep, |
| 5961 // translating the clause bodies. | 5934 // translating the clause bodies. |
| 5962 HBasicBlock* curr_test_block = first_test_block; | 5935 HBasicBlock* curr_test_block = first_test_block; |
| 5963 HBasicBlock* fall_through_block = NULL; | 5936 HBasicBlock* fall_through_block = NULL; |
| 5964 | 5937 |
| 5965 BreakAndContinueInfo break_info(stmt); | 5938 BreakAndContinueInfo break_info(stmt); |
| 5966 { BreakAndContinueScope push(&break_info, this); | 5939 { BreakAndContinueScope push(&break_info, this); |
| 5967 for (int i = 0; i < clause_count; ++i) { | 5940 for (int i = 0; i < clause_count; ++i) { |
| 5968 CaseClause* clause = clauses->at(i); | 5941 CaseClause* clause = clauses->at(i); |
| 5969 | 5942 |
| 5970 // Identify the block where normal (non-fall-through) control flow | 5943 // Identify the block where normal (non-fall-through) control flow |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6237 | 6210 |
| 6238 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | 6211 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
| 6239 ASSERT(!HasStackOverflow()); | 6212 ASSERT(!HasStackOverflow()); |
| 6240 ASSERT(current_block() != NULL); | 6213 ASSERT(current_block() != NULL); |
| 6241 ASSERT(current_block()->HasPredecessor()); | 6214 ASSERT(current_block()->HasPredecessor()); |
| 6242 | 6215 |
| 6243 if (!FLAG_optimize_for_in) { | 6216 if (!FLAG_optimize_for_in) { |
| 6244 return Bailout("ForInStatement optimization is disabled"); | 6217 return Bailout("ForInStatement optimization is disabled"); |
| 6245 } | 6218 } |
| 6246 | 6219 |
| 6247 if (!oracle()->IsForInFastCase(stmt)) { | 6220 if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) { |
| 6248 return Bailout("ForInStatement is not fast case"); | 6221 return Bailout("ForInStatement is not fast case"); |
| 6249 } | 6222 } |
| 6250 | 6223 |
| 6251 if (!stmt->each()->IsVariableProxy() || | 6224 if (!stmt->each()->IsVariableProxy() || |
| 6252 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { | 6225 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { |
| 6253 return Bailout("ForInStatement with non-local each variable"); | 6226 return Bailout("ForInStatement with non-local each variable"); |
| 6254 } | 6227 } |
| 6255 | 6228 |
| 6256 Variable* each_var = stmt->each()->AsVariableProxy()->var(); | 6229 Variable* each_var = stmt->each()->AsVariableProxy()->var(); |
| 6257 | 6230 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6378 ASSERT(!HasStackOverflow()); | 6351 ASSERT(!HasStackOverflow()); |
| 6379 ASSERT(current_block() != NULL); | 6352 ASSERT(current_block() != NULL); |
| 6380 ASSERT(current_block()->HasPredecessor()); | 6353 ASSERT(current_block()->HasPredecessor()); |
| 6381 return Bailout("DebuggerStatement"); | 6354 return Bailout("DebuggerStatement"); |
| 6382 } | 6355 } |
| 6383 | 6356 |
| 6384 | 6357 |
| 6385 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( | 6358 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( |
| 6386 Code* unoptimized_code, FunctionLiteral* expr) { | 6359 Code* unoptimized_code, FunctionLiteral* expr) { |
| 6387 int start_position = expr->start_position(); | 6360 int start_position = expr->start_position(); |
| 6388 RelocIterator it(unoptimized_code); | 6361 for (RelocIterator it(unoptimized_code); !it.done(); it.next()) { |
| 6389 for (;!it.done(); it.next()) { | |
| 6390 RelocInfo* rinfo = it.rinfo(); | 6362 RelocInfo* rinfo = it.rinfo(); |
| 6391 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; | 6363 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; |
| 6392 Object* obj = rinfo->target_object(); | 6364 Object* obj = rinfo->target_object(); |
| 6393 if (obj->IsSharedFunctionInfo()) { | 6365 if (obj->IsSharedFunctionInfo()) { |
| 6394 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 6366 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
| 6395 if (shared->start_position() == start_position) { | 6367 if (shared->start_position() == start_position) { |
| 6396 return Handle<SharedFunctionInfo>(shared); | 6368 return Handle<SharedFunctionInfo>(shared); |
| 6397 } | 6369 } |
| 6398 } | 6370 } |
| 6399 } | 6371 } |
| 6400 | 6372 |
| 6401 return Handle<SharedFunctionInfo>(); | 6373 return Handle<SharedFunctionInfo>(); |
| 6402 } | 6374 } |
| 6403 | 6375 |
| 6404 | 6376 |
| 6405 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 6377 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 6406 ASSERT(!HasStackOverflow()); | 6378 ASSERT(!HasStackOverflow()); |
| 6407 ASSERT(current_block() != NULL); | 6379 ASSERT(current_block() != NULL); |
| 6408 ASSERT(current_block()->HasPredecessor()); | 6380 ASSERT(current_block()->HasPredecessor()); |
| 6409 Handle<SharedFunctionInfo> shared_info = | 6381 Handle<SharedFunctionInfo> shared_info = |
| 6410 SearchSharedFunctionInfo(info()->shared_info()->code(), | 6382 SearchSharedFunctionInfo(info()->shared_info()->code(), expr); |
| 6411 expr); | |
| 6412 if (shared_info.is_null()) { | 6383 if (shared_info.is_null()) { |
| 6413 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); | 6384 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); |
| 6414 } | 6385 } |
| 6415 // We also have a stack overflow if the recursive compilation did. | 6386 // We also have a stack overflow if the recursive compilation did. |
| 6416 if (HasStackOverflow()) return; | 6387 if (HasStackOverflow()) return; |
| 6417 HValue* context = environment()->LookupContext(); | 6388 HValue* context = environment()->LookupContext(); |
| 6418 HFunctionLiteral* instr = | 6389 HFunctionLiteral* instr = |
| 6419 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); | 6390 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); |
| 6420 return ast_context()->ReturnInstruction(instr, expr->id()); | 6391 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 6421 } | 6392 } |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6827 Literal* key = property->key(); | 6798 Literal* key = property->key(); |
| 6828 Expression* value = property->value(); | 6799 Expression* value = property->value(); |
| 6829 | 6800 |
| 6830 switch (property->kind()) { | 6801 switch (property->kind()) { |
| 6831 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 6802 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 6832 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 6803 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 6833 // Fall through. | 6804 // Fall through. |
| 6834 case ObjectLiteral::Property::COMPUTED: | 6805 case ObjectLiteral::Property::COMPUTED: |
| 6835 if (key->handle()->IsInternalizedString()) { | 6806 if (key->handle()->IsInternalizedString()) { |
| 6836 if (property->emit_store()) { | 6807 if (property->emit_store()) { |
| 6837 property->RecordTypeFeedback(oracle()); | |
| 6838 CHECK_ALIVE(VisitForValue(value)); | 6808 CHECK_ALIVE(VisitForValue(value)); |
| 6839 HValue* value = Pop(); | 6809 HValue* value = Pop(); |
| 6840 Handle<Map> map = property->GetReceiverType(); | 6810 Handle<Map> map = property->GetReceiverType(); |
| 6841 Handle<String> name = property->key()->AsPropertyName(); | 6811 Handle<String> name = property->key()->AsPropertyName(); |
| 6842 HInstruction* store; | 6812 HInstruction* store; |
| 6843 if (map.is_null()) { | 6813 if (map.is_null()) { |
| 6844 // If we don't know the monomorphic type, do a generic store. | 6814 // If we don't know the monomorphic type, do a generic store. |
| 6845 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value)); | 6815 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value)); |
| 6846 } else { | 6816 } else { |
| 6847 #if DEBUG | 6817 #if DEBUG |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7398 ASSERT(join != NULL); | 7368 ASSERT(join != NULL); |
| 7399 join->SetJoinId(expr->id()); | 7369 join->SetJoinId(expr->id()); |
| 7400 set_current_block(join); | 7370 set_current_block(join); |
| 7401 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); | 7371 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); |
| 7402 } | 7372 } |
| 7403 | 7373 |
| 7404 | 7374 |
| 7405 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 7375 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
| 7406 Property* prop = expr->target()->AsProperty(); | 7376 Property* prop = expr->target()->AsProperty(); |
| 7407 ASSERT(prop != NULL); | 7377 ASSERT(prop != NULL); |
| 7408 expr->RecordTypeFeedback(oracle(), zone()); | |
| 7409 CHECK_ALIVE(VisitForValue(prop->obj())); | 7378 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 7410 | 7379 |
| 7411 if (prop->key()->IsPropertyName()) { | 7380 if (prop->key()->IsPropertyName()) { |
| 7412 // Named store. | 7381 // Named store. |
| 7413 CHECK_ALIVE(VisitForValue(expr->value())); | 7382 CHECK_ALIVE(VisitForValue(expr->value())); |
| 7414 HValue* value = environment()->ExpressionStackAt(0); | 7383 HValue* value = environment()->ExpressionStackAt(0); |
| 7415 HValue* object = environment()->ExpressionStackAt(1); | 7384 HValue* object = environment()->ExpressionStackAt(1); |
| 7416 | 7385 |
| 7417 Literal* key = prop->key()->AsLiteral(); | 7386 Literal* key = prop->key()->AsLiteral(); |
| 7418 Handle<String> name = Handle<String>::cast(key->handle()); | 7387 Handle<String> name = Handle<String>::cast(key->handle()); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7596 } | 7565 } |
| 7597 break; | 7566 break; |
| 7598 } | 7567 } |
| 7599 | 7568 |
| 7600 case Variable::LOOKUP: | 7569 case Variable::LOOKUP: |
| 7601 return Bailout("compound assignment to lookup slot"); | 7570 return Bailout("compound assignment to lookup slot"); |
| 7602 } | 7571 } |
| 7603 return ast_context()->ReturnValue(Pop()); | 7572 return ast_context()->ReturnValue(Pop()); |
| 7604 | 7573 |
| 7605 } else if (prop != NULL) { | 7574 } else if (prop != NULL) { |
| 7606 prop->RecordTypeFeedback(oracle(), zone()); | |
| 7607 | |
| 7608 if (prop->key()->IsPropertyName()) { | 7575 if (prop->key()->IsPropertyName()) { |
| 7609 // Named property. | 7576 // Named property. |
| 7610 CHECK_ALIVE(VisitForValue(prop->obj())); | 7577 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 7611 HValue* object = Top(); | 7578 HValue* object = Top(); |
| 7612 | 7579 |
| 7613 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 7580 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 7614 Handle<Map> map; | 7581 Handle<Map> map; |
| 7615 HInstruction* load; | 7582 HInstruction* load; |
| 7616 bool monomorphic = prop->IsMonomorphic(); | 7583 bool monomorphic = prop->IsMonomorphic(); |
| 7617 if (monomorphic) { | 7584 if (monomorphic) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7679 HValue* key = environment()->ExpressionStackAt(0); | 7646 HValue* key = environment()->ExpressionStackAt(0); |
| 7680 | 7647 |
| 7681 bool has_side_effects = false; | 7648 bool has_side_effects = false; |
| 7682 HValue* load = HandleKeyedElementAccess( | 7649 HValue* load = HandleKeyedElementAccess( |
| 7683 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, | 7650 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, |
| 7684 false, // is_store | 7651 false, // is_store |
| 7685 &has_side_effects); | 7652 &has_side_effects); |
| 7686 Push(load); | 7653 Push(load); |
| 7687 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 7654 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
| 7688 | 7655 |
| 7689 | |
| 7690 CHECK_ALIVE(VisitForValue(expr->value())); | 7656 CHECK_ALIVE(VisitForValue(expr->value())); |
| 7691 HValue* right = Pop(); | 7657 HValue* right = Pop(); |
| 7692 HValue* left = Pop(); | 7658 HValue* left = Pop(); |
| 7693 | 7659 |
| 7694 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 7660 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 7695 PushAndAdd(instr); | 7661 PushAndAdd(instr); |
| 7696 if (instr->HasObservableSideEffects()) { | 7662 if (instr->HasObservableSideEffects()) { |
| 7697 AddSimulate(operation->id(), REMOVABLE_SIMULATE); | 7663 AddSimulate(operation->id(), REMOVABLE_SIMULATE); |
| 7698 } | 7664 } |
| 7699 | 7665 |
| 7700 expr->RecordTypeFeedback(oracle(), zone()); | |
| 7701 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), | 7666 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
| 7702 RelocInfo::kNoPosition, | 7667 RelocInfo::kNoPosition, |
| 7703 true, // is_store | 7668 true, // is_store |
| 7704 &has_side_effects); | 7669 &has_side_effects); |
| 7705 | 7670 |
| 7706 // Drop the simulated receiver, key, and value. Return the value. | 7671 // Drop the simulated receiver, key, and value. Return the value. |
| 7707 Drop(3); | 7672 Drop(3); |
| 7708 Push(instr); | 7673 Push(instr); |
| 7709 ASSERT(has_side_effects); // Stores always have side effects. | 7674 ASSERT(has_side_effects); // Stores always have side effects. |
| 7710 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 7675 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| (...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8443 } | 8408 } |
| 8444 ast_context()->ReturnInstruction(result, expr->id()); | 8409 ast_context()->ReturnInstruction(result, expr->id()); |
| 8445 return true; | 8410 return true; |
| 8446 } | 8411 } |
| 8447 | 8412 |
| 8448 | 8413 |
| 8449 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 8414 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
| 8450 ASSERT(!HasStackOverflow()); | 8415 ASSERT(!HasStackOverflow()); |
| 8451 ASSERT(current_block() != NULL); | 8416 ASSERT(current_block() != NULL); |
| 8452 ASSERT(current_block()->HasPredecessor()); | 8417 ASSERT(current_block()->HasPredecessor()); |
| 8453 expr->RecordTypeFeedback(oracle(), zone()); | |
| 8454 | 8418 |
| 8455 if (TryArgumentsAccess(expr)) return; | 8419 if (TryArgumentsAccess(expr)) return; |
| 8456 | 8420 |
| 8457 CHECK_ALIVE(VisitForValue(expr->obj())); | 8421 CHECK_ALIVE(VisitForValue(expr->obj())); |
| 8458 | 8422 |
| 8459 HInstruction* instr = NULL; | 8423 HInstruction* instr = NULL; |
| 8460 if (expr->IsStringLength()) { | 8424 if (expr->IsStringLength()) { |
| 8461 HValue* string = Pop(); | 8425 HValue* string = Pop(); |
| 8462 BuildCheckNonSmi(string); | 8426 BuildCheckNonSmi(string); |
| 8463 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 8427 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8934 target_shared->EnableDeoptimizationSupport(*target_info.code()); | 8898 target_shared->EnableDeoptimizationSupport(*target_info.code()); |
| 8935 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, | 8899 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, |
| 8936 &target_info, | 8900 &target_info, |
| 8937 target_shared); | 8901 target_shared); |
| 8938 } | 8902 } |
| 8939 | 8903 |
| 8940 // ---------------------------------------------------------------- | 8904 // ---------------------------------------------------------------- |
| 8941 // After this point, we've made a decision to inline this function (so | 8905 // After this point, we've made a decision to inline this function (so |
| 8942 // TryInline should always return true). | 8906 // TryInline should always return true). |
| 8943 | 8907 |
| 8944 // Save the pending call context and type feedback oracle. Set up new ones | 8908 // Type-check the inlined function. |
| 8945 // for the inlined function. | |
| 8946 ASSERT(target_shared->has_deoptimization_support()); | 8909 ASSERT(target_shared->has_deoptimization_support()); |
| 8947 Handle<Code> unoptimized_code(target_shared->code()); | 8910 AstTyper::Type(&target_info); |
| 8948 TypeFeedbackOracle target_oracle( | 8911 |
| 8949 unoptimized_code, | 8912 // Save the pending call context. Set up new one for the inlined function. |
| 8950 Handle<Context>(target->context()->native_context()), | |
| 8951 isolate(), | |
| 8952 zone()); | |
| 8953 // The function state is new-allocated because we need to delete it | 8913 // The function state is new-allocated because we need to delete it |
| 8954 // in two different places. | 8914 // in two different places. |
| 8955 FunctionState* target_state = new FunctionState( | 8915 FunctionState* target_state = new FunctionState( |
| 8956 this, &target_info, &target_oracle, inlining_kind); | 8916 this, &target_info, inlining_kind); |
| 8957 | 8917 |
| 8958 HConstant* undefined = graph()->GetConstantUndefined(); | 8918 HConstant* undefined = graph()->GetConstantUndefined(); |
| 8959 bool undefined_receiver = HEnvironment::UseUndefinedReceiver( | 8919 bool undefined_receiver = HEnvironment::UseUndefinedReceiver( |
| 8960 target, function, call_kind, inlining_kind); | 8920 target, function, call_kind, inlining_kind); |
| 8961 HEnvironment* inner_env = | 8921 HEnvironment* inner_env = |
| 8962 environment()->CopyForInlining(target, | 8922 environment()->CopyForInlining(target, |
| 8963 arguments_count, | 8923 arguments_count, |
| 8964 function, | 8924 function, |
| 8965 undefined, | 8925 undefined, |
| 8966 function_state()->inlining_kind(), | 8926 function_state()->inlining_kind(), |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9020 TraceInline(target, caller, "inline graph construction failed"); | 8980 TraceInline(target, caller, "inline graph construction failed"); |
| 9021 target_shared->DisableOptimization("inlining bailed out"); | 8981 target_shared->DisableOptimization("inlining bailed out"); |
| 9022 inline_bailout_ = true; | 8982 inline_bailout_ = true; |
| 9023 delete target_state; | 8983 delete target_state; |
| 9024 return true; | 8984 return true; |
| 9025 } | 8985 } |
| 9026 | 8986 |
| 9027 // Update inlined nodes count. | 8987 // Update inlined nodes count. |
| 9028 inlined_count_ += nodes_added; | 8988 inlined_count_ += nodes_added; |
| 9029 | 8989 |
| 8990 Handle<Code> unoptimized_code(target_shared->code()); |
| 9030 ASSERT(unoptimized_code->kind() == Code::FUNCTION); | 8991 ASSERT(unoptimized_code->kind() == Code::FUNCTION); |
| 9031 Handle<TypeFeedbackInfo> type_info( | 8992 Handle<TypeFeedbackInfo> type_info( |
| 9032 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); | 8993 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); |
| 9033 graph()->update_type_change_checksum(type_info->own_type_change_checksum()); | 8994 graph()->update_type_change_checksum(type_info->own_type_change_checksum()); |
| 9034 | 8995 |
| 9035 TraceInline(target, caller, NULL); | 8996 TraceInline(target, caller, NULL); |
| 9036 | 8997 |
| 9037 if (current_block() != NULL) { | 8998 if (current_block() != NULL) { |
| 9038 FunctionState* state = function_state(); | 8999 FunctionState* state = function_state(); |
| 9039 if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { | 9000 if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9236 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 9197 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
| 9237 switch (id) { | 9198 switch (id) { |
| 9238 case kStringCharCodeAt: | 9199 case kStringCharCodeAt: |
| 9239 case kStringCharAt: | 9200 case kStringCharAt: |
| 9240 if (argument_count == 2 && check_type == STRING_CHECK) { | 9201 if (argument_count == 2 && check_type == STRING_CHECK) { |
| 9241 HValue* index = Pop(); | 9202 HValue* index = Pop(); |
| 9242 HValue* string = Pop(); | 9203 HValue* string = Pop(); |
| 9243 HValue* context = environment()->LookupContext(); | 9204 HValue* context = environment()->LookupContext(); |
| 9244 ASSERT(!expr->holder().is_null()); | 9205 ASSERT(!expr->holder().is_null()); |
| 9245 AddInstruction(new(zone()) HCheckPrototypeMaps( | 9206 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 9246 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), | 9207 Call::GetPrototypeForPrimitiveCheck(STRING_CHECK, |
| 9208 expr->holder()->GetIsolate()), |
| 9247 expr->holder(), | 9209 expr->holder(), |
| 9248 zone())); | 9210 zone())); |
| 9249 HInstruction* char_code = | 9211 HInstruction* char_code = |
| 9250 BuildStringCharCodeAt(context, string, index); | 9212 BuildStringCharCodeAt(context, string, index); |
| 9251 if (id == kStringCharCodeAt) { | 9213 if (id == kStringCharCodeAt) { |
| 9252 ast_context()->ReturnInstruction(char_code, expr->id()); | 9214 ast_context()->ReturnInstruction(char_code, expr->id()); |
| 9253 return true; | 9215 return true; |
| 9254 } | 9216 } |
| 9255 AddInstruction(char_code); | 9217 AddInstruction(char_code); |
| 9256 HInstruction* result = | 9218 HInstruction* result = |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9551 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 9513 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 9552 | 9514 |
| 9553 HValue* context = environment()->LookupContext(); | 9515 HValue* context = environment()->LookupContext(); |
| 9554 call = new(zone()) HCallKeyed(context, key, argument_count); | 9516 call = new(zone()) HCallKeyed(context, key, argument_count); |
| 9555 call->set_position(expr->position()); | 9517 call->set_position(expr->position()); |
| 9556 Drop(argument_count + 1); // 1 is the key. | 9518 Drop(argument_count + 1); // 1 is the key. |
| 9557 return ast_context()->ReturnInstruction(call, expr->id()); | 9519 return ast_context()->ReturnInstruction(call, expr->id()); |
| 9558 } | 9520 } |
| 9559 | 9521 |
| 9560 // Named function call. | 9522 // Named function call. |
| 9561 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); | |
| 9562 | |
| 9563 if (TryCallApply(expr)) return; | 9523 if (TryCallApply(expr)) return; |
| 9564 | 9524 |
| 9565 CHECK_ALIVE(VisitForValue(prop->obj())); | 9525 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 9566 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9526 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 9567 | 9527 |
| 9568 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 9528 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 9569 SmallMapList* types = expr->GetReceiverTypes(); | 9529 SmallMapList* types = expr->GetReceiverTypes(); |
| 9570 | 9530 |
| 9571 bool monomorphic = expr->IsMonomorphic(); | 9531 bool monomorphic = expr->IsMonomorphic(); |
| 9572 Handle<Map> receiver_map; | 9532 Handle<Map> receiver_map; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9618 HandlePolymorphicCallNamed(expr, receiver, types, name); | 9578 HandlePolymorphicCallNamed(expr, receiver, types, name); |
| 9619 return; | 9579 return; |
| 9620 | 9580 |
| 9621 } else { | 9581 } else { |
| 9622 HValue* context = environment()->LookupContext(); | 9582 HValue* context = environment()->LookupContext(); |
| 9623 call = PreProcessCall( | 9583 call = PreProcessCall( |
| 9624 new(zone()) HCallNamed(context, name, argument_count)); | 9584 new(zone()) HCallNamed(context, name, argument_count)); |
| 9625 } | 9585 } |
| 9626 | 9586 |
| 9627 } else { | 9587 } else { |
| 9628 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION); | |
| 9629 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 9588 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 9630 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); | 9589 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); |
| 9631 | 9590 |
| 9632 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 9591 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
| 9633 return Bailout("possible direct call to eval"); | 9592 return Bailout("possible direct call to eval"); |
| 9634 } | 9593 } |
| 9635 | 9594 |
| 9636 if (global_call) { | 9595 if (global_call) { |
| 9637 Variable* var = proxy->var(); | 9596 Variable* var = proxy->var(); |
| 9638 bool known_global_function = false; | 9597 bool known_global_function = false; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9754 return constructor->has_initial_map() && | 9713 return constructor->has_initial_map() && |
| 9755 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && | 9714 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && |
| 9756 constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize; | 9715 constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize; |
| 9757 } | 9716 } |
| 9758 | 9717 |
| 9759 | 9718 |
| 9760 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { | 9719 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { |
| 9761 ASSERT(!HasStackOverflow()); | 9720 ASSERT(!HasStackOverflow()); |
| 9762 ASSERT(current_block() != NULL); | 9721 ASSERT(current_block() != NULL); |
| 9763 ASSERT(current_block()->HasPredecessor()); | 9722 ASSERT(current_block()->HasPredecessor()); |
| 9764 expr->RecordTypeFeedback(oracle()); | |
| 9765 int argument_count = expr->arguments()->length() + 1; // Plus constructor. | 9723 int argument_count = expr->arguments()->length() + 1; // Plus constructor. |
| 9766 HValue* context = environment()->LookupContext(); | 9724 HValue* context = environment()->LookupContext(); |
| 9767 | 9725 |
| 9768 if (FLAG_inline_construct && | 9726 if (FLAG_inline_construct && |
| 9769 expr->IsMonomorphic() && | 9727 expr->IsMonomorphic() && |
| 9770 IsAllocationInlineable(expr->target())) { | 9728 IsAllocationInlineable(expr->target())) { |
| 9771 // The constructor function is on the stack in the unoptimized code | 9729 // The constructor function is on the stack in the unoptimized code |
| 9772 // during evaluation of the arguments. | 9730 // during evaluation of the arguments. |
| 9773 CHECK_ALIVE(VisitForValue(expr->expression())); | 9731 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 9774 HValue* function = Top(); | 9732 HValue* function = Top(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9814 CHECK_ALIVE(VisitArgument(expr->expression())); | 9772 CHECK_ALIVE(VisitArgument(expr->expression())); |
| 9815 HValue* constructor = HPushArgument::cast(Top())->argument(); | 9773 HValue* constructor = HPushArgument::cast(Top())->argument(); |
| 9816 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 9774 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 9817 HCallNew* call; | 9775 HCallNew* call; |
| 9818 if (use_call_new_array) { | 9776 if (use_call_new_array) { |
| 9819 // TODO(mvstanton): It would be better to use the already created global | 9777 // TODO(mvstanton): It would be better to use the already created global |
| 9820 // property cell that is shared by full code gen. That way, any transition | 9778 // property cell that is shared by full code gen. That way, any transition |
| 9821 // information that happened after crankshaft won't be lost. The right | 9779 // information that happened after crankshaft won't be lost. The right |
| 9822 // way to do that is to begin passing the cell to the type feedback oracle | 9780 // way to do that is to begin passing the cell to the type feedback oracle |
| 9823 // instead of just the value in the cell. Do this in a follow-up checkin. | 9781 // instead of just the value in the cell. Do this in a follow-up checkin. |
| 9824 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId()); | 9782 Handle<Smi> feedback = expr->allocation_elements_kind(); |
| 9825 ASSERT(feedback->IsSmi()); | |
| 9826 Handle<JSGlobalPropertyCell> cell = | 9783 Handle<JSGlobalPropertyCell> cell = |
| 9827 isolate()->factory()->NewJSGlobalPropertyCell(feedback); | 9784 isolate()->factory()->NewJSGlobalPropertyCell(feedback); |
| 9828 | 9785 |
| 9829 // TODO(mvstanton): Here we should probably insert code to check if the | 9786 // TODO(mvstanton): Here we should probably insert code to check if the |
| 9830 // type cell elements kind is different from when we compiled, and deopt | 9787 // type cell elements kind is different from when we compiled, and deopt |
| 9831 // in that case. Do this in a follow-up checin. | 9788 // in that case. Do this in a follow-up checin. |
| 9832 call = new(zone()) HCallNewArray(context, constructor, argument_count, | 9789 call = new(zone()) HCallNewArray(context, constructor, argument_count, |
| 9833 cell); | 9790 cell); |
| 9834 } else { | 9791 } else { |
| 9835 call = new(zone()) HCallNew(context, constructor, argument_count); | 9792 call = new(zone()) HCallNew(context, constructor, argument_count); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9903 case Token::DELETE: return VisitDelete(expr); | 9860 case Token::DELETE: return VisitDelete(expr); |
| 9904 case Token::VOID: return VisitVoid(expr); | 9861 case Token::VOID: return VisitVoid(expr); |
| 9905 case Token::TYPEOF: return VisitTypeof(expr); | 9862 case Token::TYPEOF: return VisitTypeof(expr); |
| 9906 case Token::SUB: return VisitSub(expr); | 9863 case Token::SUB: return VisitSub(expr); |
| 9907 case Token::BIT_NOT: return VisitBitNot(expr); | 9864 case Token::BIT_NOT: return VisitBitNot(expr); |
| 9908 case Token::NOT: return VisitNot(expr); | 9865 case Token::NOT: return VisitNot(expr); |
| 9909 default: UNREACHABLE(); | 9866 default: UNREACHABLE(); |
| 9910 } | 9867 } |
| 9911 } | 9868 } |
| 9912 | 9869 |
| 9870 |
| 9913 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { | 9871 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { |
| 9914 Property* prop = expr->expression()->AsProperty(); | 9872 Property* prop = expr->expression()->AsProperty(); |
| 9915 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 9873 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 9916 if (prop != NULL) { | 9874 if (prop != NULL) { |
| 9917 CHECK_ALIVE(VisitForValue(prop->obj())); | 9875 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 9918 CHECK_ALIVE(VisitForValue(prop->key())); | 9876 CHECK_ALIVE(VisitForValue(prop->key())); |
| 9919 HValue* key = Pop(); | 9877 HValue* key = Pop(); |
| 9920 HValue* obj = Pop(); | 9878 HValue* obj = Pop(); |
| 9921 HValue* context = environment()->LookupContext(); | 9879 HValue* context = environment()->LookupContext(); |
| 9922 HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key); | 9880 HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9959 return ast_context()->ReturnInstruction(instr, expr->id()); | 9917 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 9960 } | 9918 } |
| 9961 | 9919 |
| 9962 | 9920 |
| 9963 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { | 9921 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { |
| 9964 CHECK_ALIVE(VisitForValue(expr->expression())); | 9922 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 9965 HValue* value = Pop(); | 9923 HValue* value = Pop(); |
| 9966 HValue* context = environment()->LookupContext(); | 9924 HValue* context = environment()->LookupContext(); |
| 9967 HInstruction* instr = | 9925 HInstruction* instr = |
| 9968 HMul::New(zone(), context, value, graph()->GetConstantMinus1()); | 9926 HMul::New(zone(), context, value, graph()->GetConstantMinus1()); |
| 9969 TypeInfo info = oracle()->UnaryType(expr); | 9927 TypeInfo info = expr->type(); |
| 9970 Representation rep = ToRepresentation(info); | 9928 Representation rep = ToRepresentation(info); |
| 9971 if (info.IsUninitialized()) { | 9929 if (info.IsUninitialized()) { |
| 9972 AddSoftDeoptimize(); | 9930 AddSoftDeoptimize(); |
| 9973 info = TypeInfo::Unknown(); | 9931 info = TypeInfo::Unknown(); |
| 9974 } | 9932 } |
| 9975 if (instr->IsBinaryOperation()) { | 9933 if (instr->IsBinaryOperation()) { |
| 9976 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep); | 9934 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep); |
| 9977 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep); | 9935 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep); |
| 9978 } | 9936 } |
| 9979 return ast_context()->ReturnInstruction(instr, expr->id()); | 9937 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 9980 } | 9938 } |
| 9981 | 9939 |
| 9982 | 9940 |
| 9983 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { | 9941 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
| 9984 CHECK_ALIVE(VisitForValue(expr->expression())); | 9942 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 9985 HValue* value = Pop(); | 9943 HValue* value = Pop(); |
| 9986 TypeInfo info = oracle()->UnaryType(expr); | 9944 TypeInfo info = expr->type(); |
| 9987 if (info.IsUninitialized()) { | 9945 if (info.IsUninitialized()) { |
| 9988 AddSoftDeoptimize(); | 9946 AddSoftDeoptimize(); |
| 9989 } | 9947 } |
| 9990 HInstruction* instr = new(zone()) HBitNot(value); | 9948 HInstruction* instr = new(zone()) HBitNot(value); |
| 9991 return ast_context()->ReturnInstruction(instr, expr->id()); | 9949 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 9992 } | 9950 } |
| 9993 | 9951 |
| 9994 | 9952 |
| 9995 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { | 9953 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { |
| 9996 if (ast_context()->IsTest()) { | 9954 if (ast_context()->IsTest()) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10033 CreateJoin(materialize_false, materialize_true, expr->id()); | 9991 CreateJoin(materialize_false, materialize_true, expr->id()); |
| 10034 set_current_block(join); | 9992 set_current_block(join); |
| 10035 if (join != NULL) return ast_context()->ReturnValue(Pop()); | 9993 if (join != NULL) return ast_context()->ReturnValue(Pop()); |
| 10036 } | 9994 } |
| 10037 | 9995 |
| 10038 | 9996 |
| 10039 HInstruction* HOptimizedGraphBuilder::BuildIncrement( | 9997 HInstruction* HOptimizedGraphBuilder::BuildIncrement( |
| 10040 bool returns_original_input, | 9998 bool returns_original_input, |
| 10041 CountOperation* expr) { | 9999 CountOperation* expr) { |
| 10042 // The input to the count operation is on top of the expression stack. | 10000 // The input to the count operation is on top of the expression stack. |
| 10043 TypeInfo info = oracle()->IncrementType(expr); | 10001 TypeInfo info = expr->type(); |
| 10044 Representation rep = ToRepresentation(info); | 10002 Representation rep = ToRepresentation(info); |
| 10045 if (rep.IsTagged()) { | 10003 if (rep.IsTagged()) { |
| 10046 rep = Representation::Integer32(); | 10004 rep = Representation::Integer32(); |
| 10047 } | 10005 } |
| 10048 | 10006 |
| 10049 if (returns_original_input) { | 10007 if (returns_original_input) { |
| 10050 // We need an explicit HValue representing ToNumber(input). The | 10008 // We need an explicit HValue representing ToNumber(input). The |
| 10051 // actual HChange instruction we need is (sometimes) added in a later | 10009 // actual HChange instruction we need is (sometimes) added in a later |
| 10052 // phase, so it is not available now to be used as an input to HAdd and | 10010 // phase, so it is not available now to be used as an input to HAdd and |
| 10053 // as the return value. | 10011 // as the return value. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10147 break; | 10105 break; |
| 10148 } | 10106 } |
| 10149 | 10107 |
| 10150 case Variable::LOOKUP: | 10108 case Variable::LOOKUP: |
| 10151 return Bailout("lookup variable in count operation"); | 10109 return Bailout("lookup variable in count operation"); |
| 10152 } | 10110 } |
| 10153 | 10111 |
| 10154 } else { | 10112 } else { |
| 10155 // Argument of the count operation is a property. | 10113 // Argument of the count operation is a property. |
| 10156 ASSERT(prop != NULL); | 10114 ASSERT(prop != NULL); |
| 10157 prop->RecordTypeFeedback(oracle(), zone()); | |
| 10158 | 10115 |
| 10159 if (prop->key()->IsPropertyName()) { | 10116 if (prop->key()->IsPropertyName()) { |
| 10160 // Named property. | 10117 // Named property. |
| 10161 if (returns_original_input) Push(graph()->GetConstantUndefined()); | 10118 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
| 10162 | 10119 |
| 10163 CHECK_ALIVE(VisitForValue(prop->obj())); | 10120 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 10164 HValue* object = Top(); | 10121 HValue* object = Top(); |
| 10165 | 10122 |
| 10166 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 10123 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 10167 Handle<Map> map; | 10124 Handle<Map> map; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10230 HValue* load = HandleKeyedElementAccess( | 10187 HValue* load = HandleKeyedElementAccess( |
| 10231 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, | 10188 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, |
| 10232 false, // is_store | 10189 false, // is_store |
| 10233 &has_side_effects); | 10190 &has_side_effects); |
| 10234 Push(load); | 10191 Push(load); |
| 10235 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 10192 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
| 10236 | 10193 |
| 10237 after = BuildIncrement(returns_original_input, expr); | 10194 after = BuildIncrement(returns_original_input, expr); |
| 10238 input = environment()->ExpressionStackAt(0); | 10195 input = environment()->ExpressionStackAt(0); |
| 10239 | 10196 |
| 10240 expr->RecordTypeFeedback(oracle(), zone()); | |
| 10241 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), | 10197 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), |
| 10242 RelocInfo::kNoPosition, | 10198 RelocInfo::kNoPosition, |
| 10243 true, // is_store | 10199 true, // is_store |
| 10244 &has_side_effects); | 10200 &has_side_effects); |
| 10245 | 10201 |
| 10246 // Drop the key and the original value from the bailout environment. | 10202 // Drop the key and the original value from the bailout environment. |
| 10247 // Overwrite the receiver with the result of the operation, and the | 10203 // Overwrite the receiver with the result of the operation, and the |
| 10248 // placeholder with the original value if necessary. | 10204 // placeholder with the original value if necessary. |
| 10249 Drop(2); | 10205 Drop(2); |
| 10250 environment()->SetExpressionStackAt(0, after); | 10206 environment()->SetExpressionStackAt(0, after); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10339 } | 10295 } |
| 10340 return true; | 10296 return true; |
| 10341 } | 10297 } |
| 10342 | 10298 |
| 10343 | 10299 |
| 10344 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( | 10300 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
| 10345 BinaryOperation* expr, | 10301 BinaryOperation* expr, |
| 10346 HValue* left, | 10302 HValue* left, |
| 10347 HValue* right) { | 10303 HValue* right) { |
| 10348 HValue* context = environment()->LookupContext(); | 10304 HValue* context = environment()->LookupContext(); |
| 10349 TypeInfo left_info, right_info, result_info, combined_info; | 10305 TypeInfo left_info = expr->left_type(); |
| 10350 oracle()->BinaryType(expr, &left_info, &right_info, &result_info); | 10306 TypeInfo right_info = expr->right_type(); |
| 10307 TypeInfo result_info = expr->result_type(); |
| 10308 TypeInfo combined_info; |
| 10351 Representation left_rep = ToRepresentation(left_info); | 10309 Representation left_rep = ToRepresentation(left_info); |
| 10352 Representation right_rep = ToRepresentation(right_info); | 10310 Representation right_rep = ToRepresentation(right_info); |
| 10353 Representation result_rep = ToRepresentation(result_info); | 10311 Representation result_rep = ToRepresentation(result_info); |
| 10354 if (left_info.IsUninitialized()) { | 10312 if (left_info.IsUninitialized()) { |
| 10355 // Can't have initialized one but not the other. | 10313 // Can't have initialized one but not the other. |
| 10356 ASSERT(right_info.IsUninitialized()); | 10314 ASSERT(right_info.IsUninitialized()); |
| 10357 AddSoftDeoptimize(); | 10315 AddSoftDeoptimize(); |
| 10358 left_info = right_info = TypeInfo::Unknown(); | 10316 left_info = right_info = TypeInfo::Unknown(); |
| 10359 } | 10317 } |
| 10360 HInstruction* instr = NULL; | 10318 HInstruction* instr = NULL; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10498 (!is_logical_and && !left_constant->BooleanValue())) { | 10456 (!is_logical_and && !left_constant->BooleanValue())) { |
| 10499 Drop(1); // left_value. | 10457 Drop(1); // left_value. |
| 10500 CHECK_BAILOUT(VisitForValue(expr->right())); | 10458 CHECK_BAILOUT(VisitForValue(expr->right())); |
| 10501 } | 10459 } |
| 10502 return ast_context()->ReturnValue(Pop()); | 10460 return ast_context()->ReturnValue(Pop()); |
| 10503 } | 10461 } |
| 10504 | 10462 |
| 10505 // We need an extra block to maintain edge-split form. | 10463 // We need an extra block to maintain edge-split form. |
| 10506 HBasicBlock* empty_block = graph()->CreateBasicBlock(); | 10464 HBasicBlock* empty_block = graph()->CreateBasicBlock(); |
| 10507 HBasicBlock* eval_right = graph()->CreateBasicBlock(); | 10465 HBasicBlock* eval_right = graph()->CreateBasicBlock(); |
| 10508 TypeFeedbackId test_id = expr->left()->test_id(); | 10466 ToBooleanStub::Types expected(expr->left()->to_boolean_types()); |
| 10509 ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id)); | |
| 10510 HBranch* test = is_logical_and | 10467 HBranch* test = is_logical_and |
| 10511 ? new(zone()) HBranch(left_value, eval_right, empty_block, expected) | 10468 ? new(zone()) HBranch(left_value, eval_right, empty_block, expected) |
| 10512 : new(zone()) HBranch(left_value, empty_block, eval_right, expected); | 10469 : new(zone()) HBranch(left_value, empty_block, eval_right, expected); |
| 10513 current_block()->Finish(test); | 10470 current_block()->Finish(test); |
| 10514 | 10471 |
| 10515 set_current_block(eval_right); | 10472 set_current_block(eval_right); |
| 10516 Drop(1); // Value of the left subexpression. | 10473 Drop(1); // Value of the left subexpression. |
| 10517 CHECK_BAILOUT(VisitForValue(expr->right())); | 10474 CHECK_BAILOUT(VisitForValue(expr->right())); |
| 10518 | 10475 |
| 10519 HBasicBlock* join_block = | 10476 HBasicBlock* join_block = |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10667 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 10624 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 10668 HValue* value = Pop(); | 10625 HValue* value = Pop(); |
| 10669 Literal* literal = expr->right()->AsLiteral(); | 10626 Literal* literal = expr->right()->AsLiteral(); |
| 10670 Handle<String> rhs = Handle<String>::cast(literal->handle()); | 10627 Handle<String> rhs = Handle<String>::cast(literal->handle()); |
| 10671 HClassOfTestAndBranch* instr = | 10628 HClassOfTestAndBranch* instr = |
| 10672 new(zone()) HClassOfTestAndBranch(value, rhs); | 10629 new(zone()) HClassOfTestAndBranch(value, rhs); |
| 10673 instr->set_position(expr->position()); | 10630 instr->set_position(expr->position()); |
| 10674 return ast_context()->ReturnControl(instr, expr->id()); | 10631 return ast_context()->ReturnControl(instr, expr->id()); |
| 10675 } | 10632 } |
| 10676 | 10633 |
| 10677 TypeInfo left_type, right_type, overall_type_info; | 10634 TypeInfo left_type = expr->left_type(); |
| 10678 oracle()->CompareType(expr, &left_type, &right_type, &overall_type_info); | 10635 TypeInfo right_type = expr->right_type(); |
| 10679 Representation combined_rep = ToRepresentation(overall_type_info); | 10636 TypeInfo overall_type = expr->overall_type(); |
| 10637 Representation combined_rep = ToRepresentation(overall_type); |
| 10680 Representation left_rep = ToRepresentation(left_type); | 10638 Representation left_rep = ToRepresentation(left_type); |
| 10681 Representation right_rep = ToRepresentation(right_type); | 10639 Representation right_rep = ToRepresentation(right_type); |
| 10682 // Check if this expression was ever executed according to type feedback. | 10640 // Check if this expression was ever executed according to type feedback. |
| 10683 // Note that for the special typeof/null/undefined cases we get unknown here. | 10641 // Note that for the special typeof/null/undefined cases we get unknown here. |
| 10684 if (overall_type_info.IsUninitialized()) { | 10642 if (overall_type.IsUninitialized()) { |
| 10685 AddSoftDeoptimize(); | 10643 AddSoftDeoptimize(); |
| 10686 overall_type_info = left_type = right_type = TypeInfo::Unknown(); | 10644 overall_type = left_type = right_type = TypeInfo::Unknown(); |
| 10687 } | 10645 } |
| 10688 | 10646 |
| 10689 CHECK_ALIVE(VisitForValue(expr->left())); | 10647 CHECK_ALIVE(VisitForValue(expr->left())); |
| 10690 CHECK_ALIVE(VisitForValue(expr->right())); | 10648 CHECK_ALIVE(VisitForValue(expr->right())); |
| 10691 | 10649 |
| 10692 HValue* context = environment()->LookupContext(); | 10650 HValue* context = environment()->LookupContext(); |
| 10693 HValue* right = Pop(); | 10651 HValue* right = Pop(); |
| 10694 HValue* left = Pop(); | 10652 HValue* left = Pop(); |
| 10695 Token::Value op = expr->op(); | 10653 Token::Value op = expr->op(); |
| 10696 | 10654 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10748 AddInstruction(new(zone()) HCheckFunction(right, target)); | 10706 AddInstruction(new(zone()) HCheckFunction(right, target)); |
| 10749 HInstanceOfKnownGlobal* result = | 10707 HInstanceOfKnownGlobal* result = |
| 10750 new(zone()) HInstanceOfKnownGlobal(context, left, target); | 10708 new(zone()) HInstanceOfKnownGlobal(context, left, target); |
| 10751 result->set_position(expr->position()); | 10709 result->set_position(expr->position()); |
| 10752 return ast_context()->ReturnInstruction(result, expr->id()); | 10710 return ast_context()->ReturnInstruction(result, expr->id()); |
| 10753 } | 10711 } |
| 10754 } else if (op == Token::IN) { | 10712 } else if (op == Token::IN) { |
| 10755 HIn* result = new(zone()) HIn(context, left, right); | 10713 HIn* result = new(zone()) HIn(context, left, right); |
| 10756 result->set_position(expr->position()); | 10714 result->set_position(expr->position()); |
| 10757 return ast_context()->ReturnInstruction(result, expr->id()); | 10715 return ast_context()->ReturnInstruction(result, expr->id()); |
| 10758 } else if (overall_type_info.IsNonPrimitive()) { | 10716 } else if (overall_type.IsNonPrimitive()) { |
| 10759 switch (op) { | 10717 switch (op) { |
| 10760 case Token::EQ: | 10718 case Token::EQ: |
| 10761 case Token::EQ_STRICT: { | 10719 case Token::EQ_STRICT: { |
| 10762 // Can we get away with map check and not instance type check? | 10720 // Can we get away with map check and not instance type check? |
| 10763 Handle<Map> map = oracle()->GetCompareMap(expr); | 10721 Handle<Map> map = expr->map(); |
| 10764 if (!map.is_null()) { | 10722 if (!map.is_null()) { |
| 10765 AddCheckMapsWithTransitions(left, map); | 10723 AddCheckMapsWithTransitions(left, map); |
| 10766 AddCheckMapsWithTransitions(right, map); | 10724 AddCheckMapsWithTransitions(right, map); |
| 10767 HCompareObjectEqAndBranch* result = | 10725 HCompareObjectEqAndBranch* result = |
| 10768 new(zone()) HCompareObjectEqAndBranch(left, right); | 10726 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 10769 result->set_position(expr->position()); | 10727 result->set_position(expr->position()); |
| 10770 return ast_context()->ReturnControl(result, expr->id()); | 10728 return ast_context()->ReturnControl(result, expr->id()); |
| 10771 } else { | 10729 } else { |
| 10772 BuildCheckNonSmi(left); | 10730 BuildCheckNonSmi(left); |
| 10773 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); | 10731 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
| 10774 BuildCheckNonSmi(right); | 10732 BuildCheckNonSmi(right); |
| 10775 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); | 10733 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
| 10776 HCompareObjectEqAndBranch* result = | 10734 HCompareObjectEqAndBranch* result = |
| 10777 new(zone()) HCompareObjectEqAndBranch(left, right); | 10735 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 10778 result->set_position(expr->position()); | 10736 result->set_position(expr->position()); |
| 10779 return ast_context()->ReturnControl(result, expr->id()); | 10737 return ast_context()->ReturnControl(result, expr->id()); |
| 10780 } | 10738 } |
| 10781 } | 10739 } |
| 10782 default: | 10740 default: |
| 10783 return Bailout("Unsupported non-primitive compare"); | 10741 return Bailout("Unsupported non-primitive compare"); |
| 10784 } | 10742 } |
| 10785 } else if (overall_type_info.IsInternalizedString() && | 10743 } else if (overall_type.IsInternalizedString() && |
| 10786 Token::IsEqualityOp(op)) { | 10744 Token::IsEqualityOp(op)) { |
| 10787 BuildCheckNonSmi(left); | 10745 BuildCheckNonSmi(left); |
| 10788 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); | 10746 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); |
| 10789 BuildCheckNonSmi(right); | 10747 BuildCheckNonSmi(right); |
| 10790 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); | 10748 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); |
| 10791 HCompareObjectEqAndBranch* result = | 10749 HCompareObjectEqAndBranch* result = |
| 10792 new(zone()) HCompareObjectEqAndBranch(left, right); | 10750 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 10793 result->set_position(expr->position()); | 10751 result->set_position(expr->position()); |
| 10794 return ast_context()->ReturnControl(result, expr->id()); | 10752 return ast_context()->ReturnControl(result, expr->id()); |
| 10795 } else { | 10753 } else { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 10813 | 10771 |
| 10814 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 10772 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
| 10815 HValue* value, | 10773 HValue* value, |
| 10816 NilValue nil) { | 10774 NilValue nil) { |
| 10817 ASSERT(!HasStackOverflow()); | 10775 ASSERT(!HasStackOverflow()); |
| 10818 ASSERT(current_block() != NULL); | 10776 ASSERT(current_block() != NULL); |
| 10819 ASSERT(current_block()->HasPredecessor()); | 10777 ASSERT(current_block()->HasPredecessor()); |
| 10820 EqualityKind kind = | 10778 EqualityKind kind = |
| 10821 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; | 10779 expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; |
| 10822 HIfContinuation continuation; | 10780 HIfContinuation continuation; |
| 10823 TypeFeedbackId id = expr->CompareOperationFeedbackId(); | |
| 10824 CompareNilICStub::Types types; | 10781 CompareNilICStub::Types types; |
| 10825 if (kind == kStrictEquality) { | 10782 if (kind == kStrictEquality) { |
| 10826 if (nil == kNullValue) { | 10783 if (nil == kNullValue) { |
| 10827 types = CompareNilICStub::kCompareAgainstNull; | 10784 types = CompareNilICStub::kCompareAgainstNull; |
| 10828 } else { | 10785 } else { |
| 10829 types = CompareNilICStub::kCompareAgainstUndefined; | 10786 types = CompareNilICStub::kCompareAgainstUndefined; |
| 10830 } | 10787 } |
| 10831 } else { | 10788 } else { |
| 10832 types = static_cast<CompareNilICStub::Types>( | 10789 types = static_cast<CompareNilICStub::Types>(expr->compare_nil_types()); |
| 10833 oracle()->CompareNilTypes(id)); | |
| 10834 if (types == 0) types = CompareNilICStub::kFullCompare; | 10790 if (types == 0) types = CompareNilICStub::kFullCompare; |
| 10835 } | 10791 } |
| 10836 Handle<Map> map_handle(oracle()->CompareNilMonomorphicReceiverType(id)); | 10792 Handle<Map> map_handle = expr->map(); |
| 10837 BuildCompareNil(value, kind, types, map_handle, | 10793 BuildCompareNil(value, kind, types, map_handle, |
| 10838 expr->position(), &continuation); | 10794 expr->position(), &continuation); |
| 10839 return ast_context()->ReturnContinuation(&continuation, expr->id()); | 10795 return ast_context()->ReturnContinuation(&continuation, expr->id()); |
| 10840 } | 10796 } |
| 10841 | 10797 |
| 10842 | 10798 |
| 10843 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { | 10799 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { |
| 10844 // If we share optimized code between different closures, the | 10800 // If we share optimized code between different closures, the |
| 10845 // this-function is not a constant, except inside an inlined body. | 10801 // this-function is not a constant, except inside an inlined body. |
| 10846 if (function_state()->outer() != NULL) { | 10802 if (function_state()->outer() != NULL) { |
| (...skipping 1612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12459 } | 12415 } |
| 12460 } | 12416 } |
| 12461 | 12417 |
| 12462 #ifdef DEBUG | 12418 #ifdef DEBUG |
| 12463 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12419 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 12464 if (allocator_ != NULL) allocator_->Verify(); | 12420 if (allocator_ != NULL) allocator_->Verify(); |
| 12465 #endif | 12421 #endif |
| 12466 } | 12422 } |
| 12467 | 12423 |
| 12468 } } // namespace v8::internal | 12424 } } // namespace v8::internal |
| OLD | NEW |