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

Side by Side Diff: src/hydrogen.cc

Issue 15533004: Liveness analysis for environment slots in Hydrogen (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 7 years, 6 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/hydrogen-environment-liveness.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 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "hydrogen.h" 28 #include "hydrogen.h"
29 29
30 #include <algorithm> 30 #include <algorithm>
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 "hydrogen-environment-liveness.h"
36 #include "lithium-allocator.h" 37 #include "lithium-allocator.h"
37 #include "parser.h" 38 #include "parser.h"
38 #include "scopeinfo.h" 39 #include "scopeinfo.h"
39 #include "scopes.h" 40 #include "scopes.h"
40 #include "stub-cache.h" 41 #include "stub-cache.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"
(...skipping 18 matching lines...) Expand all
64 loop_information_(NULL), 65 loop_information_(NULL),
65 predecessors_(2, graph->zone()), 66 predecessors_(2, graph->zone()),
66 dominator_(NULL), 67 dominator_(NULL),
67 dominated_blocks_(4, graph->zone()), 68 dominated_blocks_(4, graph->zone()),
68 last_environment_(NULL), 69 last_environment_(NULL),
69 argument_count_(-1), 70 argument_count_(-1),
70 first_instruction_index_(-1), 71 first_instruction_index_(-1),
71 last_instruction_index_(-1), 72 last_instruction_index_(-1),
72 deleted_phis_(4, graph->zone()), 73 deleted_phis_(4, graph->zone()),
73 parent_loop_header_(NULL), 74 parent_loop_header_(NULL),
75 inlined_entry_block_(NULL),
74 is_inline_return_target_(false), 76 is_inline_return_target_(false),
75 is_deoptimizing_(false), 77 is_deoptimizing_(false),
76 dominates_loop_successors_(false), 78 dominates_loop_successors_(false),
77 is_osr_entry_(false) { } 79 is_osr_entry_(false) { }
78 80
79 81
80 Isolate* HBasicBlock::isolate() const { 82 Isolate* HBasicBlock::isolate() const {
81 return graph_->isolate(); 83 return graph_->isolate();
82 } 84 }
83 85
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 first_ = last_ = entry; 125 first_ = last_ = entry;
124 } 126 }
125 instr->InsertAfter(last_); 127 instr->InsertAfter(last_);
126 } 128 }
127 129
128 130
129 HDeoptimize* HBasicBlock::CreateDeoptimize( 131 HDeoptimize* HBasicBlock::CreateDeoptimize(
130 HDeoptimize::UseEnvironment has_uses) { 132 HDeoptimize::UseEnvironment has_uses) {
131 ASSERT(HasEnvironment()); 133 ASSERT(HasEnvironment());
132 if (has_uses == HDeoptimize::kNoUses) 134 if (has_uses == HDeoptimize::kNoUses)
133 return new(zone()) HDeoptimize(0, zone()); 135 return new(zone()) HDeoptimize(0, 0, 0, zone());
134 136
135 HEnvironment* environment = last_environment(); 137 HEnvironment* environment = last_environment();
136 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length(), zone()); 138 int first_local_index = environment->first_local_index();
139 int first_expression_index = environment->first_expression_index();
140 HDeoptimize* instr = new(zone()) HDeoptimize(
141 environment->length(), first_local_index, first_expression_index, zone());
137 for (int i = 0; i < environment->length(); i++) { 142 for (int i = 0; i < environment->length(); i++) {
138 HValue* val = environment->values()->at(i); 143 HValue* val = environment->values()->at(i);
139 instr->AddEnvironmentValue(val, zone()); 144 instr->AddEnvironmentValue(val, zone());
140 } 145 }
141 146
142 return instr; 147 return instr;
143 } 148 }
144 149
145 150
146 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, 151 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
147 RemovableSimulate removable) { 152 RemovableSimulate removable) {
148 ASSERT(HasEnvironment()); 153 ASSERT(HasEnvironment());
149 HEnvironment* environment = last_environment(); 154 HEnvironment* environment = last_environment();
150 ASSERT(ast_id.IsNone() || 155 ASSERT(ast_id.IsNone() ||
151 ast_id == BailoutId::StubEntry() || 156 ast_id == BailoutId::StubEntry() ||
152 environment->closure()->shared()->VerifyBailoutId(ast_id)); 157 environment->closure()->shared()->VerifyBailoutId(ast_id));
153 158
154 int push_count = environment->push_count(); 159 int push_count = environment->push_count();
155 int pop_count = environment->pop_count(); 160 int pop_count = environment->pop_count();
156 161
157 HSimulate* instr = 162 HSimulate* instr =
158 new(zone()) HSimulate(ast_id, pop_count, zone(), removable); 163 new(zone()) HSimulate(ast_id, pop_count, zone(), removable);
164 #ifdef DEBUG
165 instr->set_closure(environment->closure());
166 #endif
159 // Order of pushed values: newest (top of stack) first. This allows 167 // Order of pushed values: newest (top of stack) first. This allows
160 // HSimulate::MergeInto() to easily append additional pushed values 168 // HSimulate::MergeInto() to easily append additional pushed values
161 // that are older (from further down the stack). 169 // that are older (from further down the stack).
162 for (int i = 0; i < push_count; ++i) { 170 for (int i = 0; i < push_count; ++i) {
163 instr->AddPushedValue(environment->ExpressionStackAt(i)); 171 instr->AddPushedValue(environment->ExpressionStackAt(i));
164 } 172 }
165 for (GrowableBitVector::Iterator it(environment->assigned_variables(), 173 for (GrowableBitVector::Iterator it(environment->assigned_variables(),
166 zone()); 174 zone());
167 !it.Done(); 175 !it.Done();
168 it.Advance()) { 176 it.Advance()) {
(...skipping 16 matching lines...) Expand all
185 193
186 194
187 void HBasicBlock::Goto(HBasicBlock* block, 195 void HBasicBlock::Goto(HBasicBlock* block,
188 FunctionState* state, 196 FunctionState* state,
189 bool add_simulate) { 197 bool add_simulate) {
190 bool drop_extra = state != NULL && 198 bool drop_extra = state != NULL &&
191 state->inlining_kind() == DROP_EXTRA_ON_RETURN; 199 state->inlining_kind() == DROP_EXTRA_ON_RETURN;
192 200
193 if (block->IsInlineReturnTarget()) { 201 if (block->IsInlineReturnTarget()) {
194 AddInstruction(new(zone()) HLeaveInlined()); 202 AddInstruction(new(zone()) HLeaveInlined());
195 last_environment_ = last_environment()->DiscardInlined(drop_extra); 203 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra));
196 } 204 }
197 205
198 if (add_simulate) AddSimulate(BailoutId::None()); 206 if (add_simulate) AddSimulate(BailoutId::None());
199 HGoto* instr = new(zone()) HGoto(block); 207 HGoto* instr = new(zone()) HGoto(block);
200 Finish(instr); 208 Finish(instr);
201 } 209 }
202 210
203 211
204 void HBasicBlock::AddLeaveInlined(HValue* return_value, 212 void HBasicBlock::AddLeaveInlined(HValue* return_value,
205 FunctionState* state) { 213 FunctionState* state) {
206 HBasicBlock* target = state->function_return(); 214 HBasicBlock* target = state->function_return();
207 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; 215 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN;
208 216
209 ASSERT(target->IsInlineReturnTarget()); 217 ASSERT(target->IsInlineReturnTarget());
210 ASSERT(return_value != NULL); 218 ASSERT(return_value != NULL);
211 AddInstruction(new(zone()) HLeaveInlined()); 219 AddInstruction(new(zone()) HLeaveInlined());
212 last_environment_ = last_environment()->DiscardInlined(drop_extra); 220 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra));
213 last_environment()->Push(return_value); 221 last_environment()->Push(return_value);
214 AddSimulate(BailoutId::None()); 222 AddSimulate(BailoutId::None());
215 HGoto* instr = new(zone()) HGoto(target); 223 HGoto* instr = new(zone()) HGoto(target);
216 Finish(instr); 224 Finish(instr);
217 } 225 }
218 226
219 227
220 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { 228 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) {
221 ASSERT(!HasEnvironment()); 229 ASSERT(!HasEnvironment());
222 ASSERT(first() == NULL); 230 ASSERT(first() == NULL);
223 UpdateEnvironment(env); 231 UpdateEnvironment(env);
224 } 232 }
225 233
226 234
235 void HBasicBlock::UpdateEnvironment(HEnvironment* env) {
236 last_environment_ = env;
237 graph()->update_maximum_environment_size(env->first_expression_index());
238 }
239
240
227 void HBasicBlock::SetJoinId(BailoutId ast_id) { 241 void HBasicBlock::SetJoinId(BailoutId ast_id) {
228 int length = predecessors_.length(); 242 int length = predecessors_.length();
229 ASSERT(length > 0); 243 ASSERT(length > 0);
230 for (int i = 0; i < length; i++) { 244 for (int i = 0; i < length; i++) {
231 HBasicBlock* predecessor = predecessors_[i]; 245 HBasicBlock* predecessor = predecessors_[i];
232 ASSERT(predecessor->end()->IsGoto()); 246 ASSERT(predecessor->end()->IsGoto());
233 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); 247 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous());
234 ASSERT(i != 0 || 248 ASSERT(i != 0 ||
235 (predecessor->last_environment()->closure().is_null() || 249 (predecessor->last_environment()->closure().is_null() ||
236 predecessor->last_environment()->closure()->shared() 250 predecessor->last_environment()->closure()->shared()
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 input_representation); 738 input_representation);
725 compare->AssumeRepresentation(input_representation); 739 compare->AssumeRepresentation(input_representation);
726 AddCompare(compare); 740 AddCompare(compare);
727 return compare; 741 return compare;
728 } 742 }
729 743
730 744
731 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left, 745 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left,
732 Handle<Map> map) { 746 Handle<Map> map) {
733 HCompareMap* compare = 747 HCompareMap* compare =
734 new(zone()) HCompareMap(left, map, 748 new(zone()) HCompareMap(left, map, first_true_block_, first_false_block_);
735 first_true_block_, first_false_block_);
736 AddCompare(compare); 749 AddCompare(compare);
737 return compare; 750 return compare;
738 } 751 }
739 752
740 753
741 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { 754 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) {
742 if (split_edge_merge_block_ != NULL) { 755 if (split_edge_merge_block_ != NULL) {
743 HEnvironment* env = first_false_block_->last_environment(); 756 HEnvironment* env = first_false_block_->last_environment();
744 HBasicBlock* split_edge = 757 HBasicBlock* split_edge =
745 builder_->CreateBasicBlock(env->Copy()); 758 builder_->CreateBasicBlock(env->Copy());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 End(); 817 End();
805 } 818 }
806 819
807 820
808 void HGraphBuilder::IfBuilder::Then() { 821 void HGraphBuilder::IfBuilder::Then() {
809 ASSERT(!captured_); 822 ASSERT(!captured_);
810 ASSERT(!finished_); 823 ASSERT(!finished_);
811 did_then_ = true; 824 did_then_ = true;
812 if (needs_compare_) { 825 if (needs_compare_) {
813 // Handle if's without any expressions, they jump directly to the "else" 826 // Handle if's without any expressions, they jump directly to the "else"
814 // branch. 827 // branch. However, we must pretend that the "then" branch is reachable,
815 builder_->current_block()->GotoNoSimulate(first_false_block_); 828 // so that the graph builder visits it and sees any live range extending
816 first_true_block_ = NULL; 829 // constructs within it.
830 HConstant* constant_false = builder_->graph()->GetConstantFalse();
831 ToBooleanStub::Types boolean_type = ToBooleanStub::no_types();
832 boolean_type.Add(ToBooleanStub::BOOLEAN);
833 HBranch* branch =
834 new(zone()) HBranch(constant_false, first_true_block_,
835 first_false_block_, boolean_type);
836 builder_->current_block()->Finish(branch);
817 } 837 }
818 builder_->set_current_block(first_true_block_); 838 builder_->set_current_block(first_true_block_);
819 } 839 }
820 840
821 841
822 void HGraphBuilder::IfBuilder::Else() { 842 void HGraphBuilder::IfBuilder::Else() {
823 ASSERT(did_then_); 843 ASSERT(did_then_);
824 ASSERT(!captured_); 844 ASSERT(!captured_);
825 ASSERT(!finished_); 845 ASSERT(!finished_);
826 last_true_block_ = builder_->current_block(); 846 last_true_block_ = builder_->current_block();
(...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after
2096 blocks_(8, info->zone()), 2116 blocks_(8, info->zone()),
2097 values_(16, info->zone()), 2117 values_(16, info->zone()),
2098 phi_list_(NULL), 2118 phi_list_(NULL),
2099 uint32_instructions_(NULL), 2119 uint32_instructions_(NULL),
2100 info_(info), 2120 info_(info),
2101 zone_(info->zone()), 2121 zone_(info->zone()),
2102 is_recursive_(false), 2122 is_recursive_(false),
2103 use_optimistic_licm_(false), 2123 use_optimistic_licm_(false),
2104 has_soft_deoptimize_(false), 2124 has_soft_deoptimize_(false),
2105 depends_on_empty_array_proto_elements_(false), 2125 depends_on_empty_array_proto_elements_(false),
2106 type_change_checksum_(0) { 2126 type_change_checksum_(0),
2127 maximum_environment_size_(0) {
2107 if (info->IsStub()) { 2128 if (info->IsStub()) {
2108 HydrogenCodeStub* stub = info->code_stub(); 2129 HydrogenCodeStub* stub = info->code_stub();
2109 CodeStubInterfaceDescriptor* descriptor = 2130 CodeStubInterfaceDescriptor* descriptor =
2110 stub->GetInterfaceDescriptor(isolate_); 2131 stub->GetInterfaceDescriptor(isolate_);
2111 start_environment_ = 2132 start_environment_ =
2112 new(zone_) HEnvironment(zone_, descriptor->environment_length()); 2133 new(zone_) HEnvironment(zone_, descriptor->environment_length());
2113 } else { 2134 } else {
2114 start_environment_ = 2135 start_environment_ =
2115 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); 2136 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
2116 } 2137 }
(...skipping 2307 matching lines...) Expand 10 before | Expand all | Expand 10 after
4424 function_return_(NULL), 4445 function_return_(NULL),
4425 test_context_(NULL), 4446 test_context_(NULL),
4426 entry_(NULL), 4447 entry_(NULL),
4427 arguments_elements_(NULL), 4448 arguments_elements_(NULL),
4428 outer_(owner->function_state()) { 4449 outer_(owner->function_state()) {
4429 if (outer_ != NULL) { 4450 if (outer_ != NULL) {
4430 // State for an inline function. 4451 // State for an inline function.
4431 if (owner->ast_context()->IsTest()) { 4452 if (owner->ast_context()->IsTest()) {
4432 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); 4453 HBasicBlock* if_true = owner->graph()->CreateBasicBlock();
4433 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); 4454 HBasicBlock* if_false = owner->graph()->CreateBasicBlock();
4434 if_true->MarkAsInlineReturnTarget(); 4455 if_true->MarkAsInlineReturnTarget(owner->current_block());
4435 if_false->MarkAsInlineReturnTarget(); 4456 if_false->MarkAsInlineReturnTarget(owner->current_block());
4436 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); 4457 TestContext* outer_test_context = TestContext::cast(owner->ast_context());
4437 Expression* cond = outer_test_context->condition(); 4458 Expression* cond = outer_test_context->condition();
4438 TypeFeedbackOracle* outer_oracle = outer_test_context->oracle(); 4459 TypeFeedbackOracle* outer_oracle = outer_test_context->oracle();
4439 // The AstContext constructor pushed on the context stack. This newed 4460 // The AstContext constructor pushed on the context stack. This newed
4440 // instance is the reason that AstContext can't be BASE_EMBEDDED. 4461 // instance is the reason that AstContext can't be BASE_EMBEDDED.
4441 test_context_ = 4462 test_context_ =
4442 new TestContext(owner, cond, outer_oracle, if_true, if_false); 4463 new TestContext(owner, cond, outer_oracle, if_true, if_false);
4443 } else { 4464 } else {
4444 function_return_ = owner->graph()->CreateBasicBlock(); 4465 function_return_ = owner->graph()->CreateBasicBlock();
4445 function_return()->MarkAsInlineReturnTarget(); 4466 function_return()->MarkAsInlineReturnTarget(owner->current_block());
4446 } 4467 }
4447 // Set this after possibly allocating a new TestContext above. 4468 // Set this after possibly allocating a new TestContext above.
4448 call_context_ = owner->ast_context(); 4469 call_context_ = owner->ast_context();
4449 } 4470 }
4450 4471
4451 // Push on the state stack. 4472 // Push on the state stack.
4452 owner->set_function_state(this); 4473 owner->set_function_state(this);
4453 } 4474 }
4454 4475
4455 4476
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
4855 // zero-valued constant in the graph together. 4876 // zero-valued constant in the graph together.
4856 // The constant is needed to make idef-based bounds check work: the pass 4877 // The constant is needed to make idef-based bounds check work: the pass
4857 // evaluates relations with "zero" and that zero cannot be created after GVN. 4878 // evaluates relations with "zero" and that zero cannot be created after GVN.
4858 GetConstant0(); 4879 GetConstant0();
4859 4880
4860 #ifdef DEBUG 4881 #ifdef DEBUG
4861 // Do a full verify after building the graph and computing dominators. 4882 // Do a full verify after building the graph and computing dominators.
4862 Verify(true); 4883 Verify(true);
4863 #endif 4884 #endif
4864 4885
4886 if (FLAG_analyze_environment_liveness) {
4887 EnvironmentSlotLivenessAnalyzer esla(this);
4888 esla.AnalyzeAndTrim();
4889 }
4890
4865 PropagateDeoptimizingMark(); 4891 PropagateDeoptimizingMark();
4866 if (!CheckConstPhiUses()) { 4892 if (!CheckConstPhiUses()) {
4867 *bailout_reason = SmartArrayPointer<char>(StrDup( 4893 *bailout_reason = SmartArrayPointer<char>(StrDup(
4868 "Unsupported phi use of const variable")); 4894 "Unsupported phi use of const variable"));
4869 return false; 4895 return false;
4870 } 4896 }
4871 EliminateRedundantPhis(); 4897 EliminateRedundantPhis();
4872 if (!CheckArgumentsPhiUses()) { 4898 if (!CheckArgumentsPhiUses()) {
4873 *bailout_reason = SmartArrayPointer<char>(StrDup( 4899 *bailout_reason = SmartArrayPointer<char>(StrDup(
4874 "Unsupported phi use of arguments")); 4900 "Unsupported phi use of arguments"));
(...skipping 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after
6546 global_object, 6572 global_object,
6547 variable->name(), 6573 variable->name(),
6548 ast_context()->is_for_typeof()); 6574 ast_context()->is_for_typeof());
6549 instr->set_position(expr->position()); 6575 instr->set_position(expr->position());
6550 return ast_context()->ReturnInstruction(instr, expr->id()); 6576 return ast_context()->ReturnInstruction(instr, expr->id());
6551 } 6577 }
6552 } 6578 }
6553 6579
6554 case Variable::PARAMETER: 6580 case Variable::PARAMETER:
6555 case Variable::LOCAL: { 6581 case Variable::LOCAL: {
6556 HValue* value = environment()->Lookup(variable); 6582 HValue* value = LookupAndMakeLive(variable);
6557 if (value == graph()->GetConstantHole()) { 6583 if (value == graph()->GetConstantHole()) {
6558 ASSERT(IsDeclaredVariableMode(variable->mode()) && 6584 ASSERT(IsDeclaredVariableMode(variable->mode()) &&
6559 variable->mode() != VAR); 6585 variable->mode() != VAR);
6560 return Bailout("reference to uninitialized variable"); 6586 return Bailout("reference to uninitialized variable");
6561 } 6587 }
6562 return ast_context()->ReturnValue(value); 6588 return ast_context()->ReturnValue(value);
6563 } 6589 }
6564 6590
6565 case Variable::CONTEXT: { 6591 case Variable::CONTEXT: {
6566 HValue* context = BuildContextChainWalk(variable); 6592 HValue* context = BuildContextChainWalk(variable);
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
7546 Top(), 7572 Top(),
7547 expr->position(), 7573 expr->position(),
7548 expr->AssignmentId()); 7574 expr->AssignmentId());
7549 break; 7575 break;
7550 7576
7551 case Variable::PARAMETER: 7577 case Variable::PARAMETER:
7552 case Variable::LOCAL: 7578 case Variable::LOCAL:
7553 if (var->mode() == CONST) { 7579 if (var->mode() == CONST) {
7554 return Bailout("unsupported const compound assignment"); 7580 return Bailout("unsupported const compound assignment");
7555 } 7581 }
7556 Bind(var, Top()); 7582 BindIfLive(var, Top());
7557 break; 7583 break;
7558 7584
7559 case Variable::CONTEXT: { 7585 case Variable::CONTEXT: {
7560 // Bail out if we try to mutate a parameter value in a function 7586 // Bail out if we try to mutate a parameter value in a function
7561 // using the arguments object. We do not (yet) correctly handle the 7587 // using the arguments object. We do not (yet) correctly handle the
7562 // arguments property of the function. 7588 // arguments property of the function.
7563 if (info()->scope()->arguments() != NULL) { 7589 if (info()->scope()->arguments() != NULL) {
7564 // Parameters will be allocated to context slots. We have no 7590 // Parameters will be allocated to context slots. We have no
7565 // direct way to detect that the variable is a parameter so we do 7591 // direct way to detect that the variable is a parameter so we do
7566 // a linear search of the parameter variables. 7592 // a linear search of the parameter variables.
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
7775 HValue* env_value = environment()->Lookup(var); 7801 HValue* env_value = environment()->Lookup(var);
7776 if (env_value == graph()->GetConstantHole()) { 7802 if (env_value == graph()->GetConstantHole()) {
7777 return Bailout("assignment to let variable before initialization"); 7803 return Bailout("assignment to let variable before initialization");
7778 } 7804 }
7779 } 7805 }
7780 // We do not allow the arguments object to occur in a context where it 7806 // We do not allow the arguments object to occur in a context where it
7781 // may escape, but assignments to stack-allocated locals are 7807 // may escape, but assignments to stack-allocated locals are
7782 // permitted. 7808 // permitted.
7783 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); 7809 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED));
7784 HValue* value = Pop(); 7810 HValue* value = Pop();
7785 Bind(var, value); 7811 BindIfLive(var, value);
7786 return ast_context()->ReturnValue(value); 7812 return ast_context()->ReturnValue(value);
7787 } 7813 }
7788 7814
7789 case Variable::CONTEXT: { 7815 case Variable::CONTEXT: {
7790 // Bail out if we try to mutate a parameter value in a function using 7816 // Bail out if we try to mutate a parameter value in a function using
7791 // the arguments object. We do not (yet) correctly handle the 7817 // the arguments object. We do not (yet) correctly handle the
7792 // arguments property of the function. 7818 // arguments property of the function.
7793 if (info()->scope()->arguments() != NULL) { 7819 if (info()->scope()->arguments() != NULL) {
7794 // Parameters will rewrite to context slots. We have no direct way 7820 // Parameters will rewrite to context slots. We have no direct way
7795 // to detect that the variable is a parameter. 7821 // to detect that the variable is a parameter.
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
8995 } 9021 }
8996 } 9022 }
8997 9023
8998 HEnterInlined* enter_inlined = 9024 HEnterInlined* enter_inlined =
8999 new(zone()) HEnterInlined(target, 9025 new(zone()) HEnterInlined(target,
9000 arguments_count, 9026 arguments_count,
9001 function, 9027 function,
9002 function_state()->inlining_kind(), 9028 function_state()->inlining_kind(),
9003 function->scope()->arguments(), 9029 function->scope()->arguments(),
9004 arguments_values, 9030 arguments_values,
9005 undefined_receiver); 9031 undefined_receiver,
9032 zone());
9006 function_state()->set_entry(enter_inlined); 9033 function_state()->set_entry(enter_inlined);
9007 AddInstruction(enter_inlined); 9034 AddInstruction(enter_inlined);
9008 9035
9009 // If the function uses arguments object create and bind one. 9036 // If the function uses arguments object create and bind one.
9010 if (function->scope()->arguments() != NULL) { 9037 if (function->scope()->arguments() != NULL) {
9011 ASSERT(function->scope()->arguments()->IsStackAllocated()); 9038 ASSERT(function->scope()->arguments()->IsStackAllocated());
9012 inner_env->Bind(function->scope()->arguments(), 9039 inner_env->Bind(function->scope()->arguments(),
9013 graph()->GetArgumentsObject()); 9040 graph()->GetArgumentsObject());
9014 } 9041 }
9015 9042
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
9074 current_block()->AddLeaveInlined(undefined, state); 9101 current_block()->AddLeaveInlined(undefined, state);
9075 } 9102 }
9076 } 9103 }
9077 } 9104 }
9078 9105
9079 // Fix up the function exits. 9106 // Fix up the function exits.
9080 if (inlined_test_context() != NULL) { 9107 if (inlined_test_context() != NULL) {
9081 HBasicBlock* if_true = inlined_test_context()->if_true(); 9108 HBasicBlock* if_true = inlined_test_context()->if_true();
9082 HBasicBlock* if_false = inlined_test_context()->if_false(); 9109 HBasicBlock* if_false = inlined_test_context()->if_false();
9083 9110
9111 HEnterInlined* entry = function_state()->entry();
9112
9084 // Pop the return test context from the expression context stack. 9113 // Pop the return test context from the expression context stack.
9085 ASSERT(ast_context() == inlined_test_context()); 9114 ASSERT(ast_context() == inlined_test_context());
9086 ClearInlinedTestContext(); 9115 ClearInlinedTestContext();
9087 delete target_state; 9116 delete target_state;
9088 9117
9089 // Forward to the real test context. 9118 // Forward to the real test context.
9090 if (if_true->HasPredecessor()) { 9119 if (if_true->HasPredecessor()) {
9120 entry->RegisterReturnTarget(if_true, zone());
9091 if_true->SetJoinId(ast_id); 9121 if_true->SetJoinId(ast_id);
9092 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 9122 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
9093 if_true->Goto(true_target, function_state()); 9123 if_true->Goto(true_target, function_state());
9094 } 9124 }
9095 if (if_false->HasPredecessor()) { 9125 if (if_false->HasPredecessor()) {
9126 entry->RegisterReturnTarget(if_false, zone());
9096 if_false->SetJoinId(ast_id); 9127 if_false->SetJoinId(ast_id);
9097 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); 9128 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
9098 if_false->Goto(false_target, function_state()); 9129 if_false->Goto(false_target, function_state());
9099 } 9130 }
9100 set_current_block(NULL); 9131 set_current_block(NULL);
9101 return true; 9132 return true;
9102 9133
9103 } else if (function_return()->HasPredecessor()) { 9134 } else if (function_return()->HasPredecessor()) {
9135 function_state()->entry()->RegisterReturnTarget(function_return(), zone());
9104 function_return()->SetJoinId(ast_id); 9136 function_return()->SetJoinId(ast_id);
9105 set_current_block(function_return()); 9137 set_current_block(function_return());
9106 } else { 9138 } else {
9107 set_current_block(NULL); 9139 set_current_block(NULL);
9108 } 9140 }
9109 delete target_state; 9141 delete target_state;
9110 return true; 9142 return true;
9111 } 9143 }
9112 9144
9113 9145
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
9400 return false; 9432 return false;
9401 } 9433 }
9402 9434
9403 if (info()->scope()->arguments() == NULL) return false; 9435 if (info()->scope()->arguments() == NULL) return false;
9404 9436
9405 ZoneList<Expression*>* args = expr->arguments(); 9437 ZoneList<Expression*>* args = expr->arguments();
9406 if (args->length() != 2) return false; 9438 if (args->length() != 2) return false;
9407 9439
9408 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 9440 VariableProxy* arg_two = args->at(1)->AsVariableProxy();
9409 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; 9441 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
9410 HValue* arg_two_value = environment()->Lookup(arg_two->var()); 9442 HValue* arg_two_value = LookupAndMakeLive(arg_two->var());
9411 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; 9443 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
9412 9444
9413 // Found pattern f.apply(receiver, arguments). 9445 // Found pattern f.apply(receiver, arguments).
9414 VisitForValue(prop->obj()); 9446 VisitForValue(prop->obj());
9415 if (HasStackOverflow() || current_block() == NULL) return true; 9447 if (HasStackOverflow() || current_block() == NULL) return true;
9416 HValue* function = Top(); 9448 HValue* function = Top();
9417 AddCheckConstantFunction(expr->holder(), function, function_map); 9449 AddCheckConstantFunction(expr->holder(), function, function_map);
9418 Drop(1); 9450 Drop(1);
9419 9451
9420 VisitForValue(args->at(0)); 9452 VisitForValue(args->at(0));
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
10111 switch (var->location()) { 10143 switch (var->location()) {
10112 case Variable::UNALLOCATED: 10144 case Variable::UNALLOCATED:
10113 HandleGlobalVariableAssignment(var, 10145 HandleGlobalVariableAssignment(var,
10114 after, 10146 after,
10115 expr->position(), 10147 expr->position(),
10116 expr->AssignmentId()); 10148 expr->AssignmentId());
10117 break; 10149 break;
10118 10150
10119 case Variable::PARAMETER: 10151 case Variable::PARAMETER:
10120 case Variable::LOCAL: 10152 case Variable::LOCAL:
10121 Bind(var, after); 10153 BindIfLive(var, after);
10122 break; 10154 break;
10123 10155
10124 case Variable::CONTEXT: { 10156 case Variable::CONTEXT: {
10125 // Bail out if we try to mutate a parameter value in a function 10157 // Bail out if we try to mutate a parameter value in a function
10126 // using the arguments object. We do not (yet) correctly handle the 10158 // using the arguments object. We do not (yet) correctly handle the
10127 // arguments property of the function. 10159 // arguments property of the function.
10128 if (info()->scope()->arguments() != NULL) { 10160 if (info()->scope()->arguments() != NULL) {
10129 // Parameters will rewrite to context slots. We have no direct 10161 // Parameters will rewrite to context slots. We have no direct
10130 // way to detect that the variable is a parameter so we use a 10162 // way to detect that the variable is a parameter so we use a
10131 // linear search of the parameter list. 10163 // linear search of the parameter list.
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after
11194 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); 11226 Compiler::BuildFunctionInfo(declaration->fun(), info()->script());
11195 // Check for stack-overflow exception. 11227 // Check for stack-overflow exception.
11196 if (function.is_null()) return SetStackOverflow(); 11228 if (function.is_null()) return SetStackOverflow();
11197 globals_.Add(function, zone()); 11229 globals_.Add(function, zone());
11198 return; 11230 return;
11199 } 11231 }
11200 case Variable::PARAMETER: 11232 case Variable::PARAMETER:
11201 case Variable::LOCAL: { 11233 case Variable::LOCAL: {
11202 CHECK_ALIVE(VisitForValue(declaration->fun())); 11234 CHECK_ALIVE(VisitForValue(declaration->fun()));
11203 HValue* value = Pop(); 11235 HValue* value = Pop();
11204 environment()->Bind(variable, value); 11236 BindIfLive(variable, value);
11205 break; 11237 break;
11206 } 11238 }
11207 case Variable::CONTEXT: { 11239 case Variable::CONTEXT: {
11208 CHECK_ALIVE(VisitForValue(declaration->fun())); 11240 CHECK_ALIVE(VisitForValue(declaration->fun()));
11209 HValue* value = Pop(); 11241 HValue* value = Pop();
11210 HValue* context = environment()->LookupContext(); 11242 HValue* context = environment()->LookupContext();
11211 HStoreContextSlot* store = new(zone()) HStoreContextSlot( 11243 HStoreContextSlot* store = new(zone()) HStoreContextSlot(
11212 context, variable->index(), HStoreContextSlot::kNoCheck, value); 11244 context, variable->index(), HStoreContextSlot::kNoCheck, value);
11213 AddInstruction(store); 11245 AddInstruction(store);
11214 if (store->HasObservableSideEffects()) { 11246 if (store->HasObservableSideEffects()) {
(...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after
12471 } 12503 }
12472 } 12504 }
12473 12505
12474 #ifdef DEBUG 12506 #ifdef DEBUG
12475 if (graph_ != NULL) graph_->Verify(false); // No full verify. 12507 if (graph_ != NULL) graph_->Verify(false); // No full verify.
12476 if (allocator_ != NULL) allocator_->Verify(); 12508 if (allocator_ != NULL) allocator_->Verify();
12477 #endif 12509 #endif
12478 } 12510 }
12479 12511
12480 } } // namespace v8::internal 12512 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-environment-liveness.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698