Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: src/hydrogen.cc

Issue 14990014: Collect type feedback in separate pass and store it in AST (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Consistent check-alive Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/type-info.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/type-info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698