OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 | 121 |
122 HSimulate* HBasicBlock::CreateSimulate(int id) { | 122 HSimulate* HBasicBlock::CreateSimulate(int id) { |
123 ASSERT(HasEnvironment()); | 123 ASSERT(HasEnvironment()); |
124 HEnvironment* environment = last_environment(); | 124 HEnvironment* environment = last_environment(); |
125 ASSERT(id == AstNode::kNoNumber || | 125 ASSERT(id == AstNode::kNoNumber || |
126 environment->closure()->shared()->VerifyBailoutId(id)); | 126 environment->closure()->shared()->VerifyBailoutId(id)); |
127 | 127 |
128 int push_count = environment->push_count(); | 128 int push_count = environment->push_count(); |
129 int pop_count = environment->pop_count(); | 129 int pop_count = environment->pop_count(); |
130 | 130 |
131 int length = environment->values()->length(); | 131 int length = environment->length(); |
132 HSimulate* instr = new HSimulate(id, pop_count, length); | 132 HSimulate* instr = new HSimulate(id, pop_count, length); |
133 for (int i = push_count - 1; i >= 0; --i) { | 133 for (int i = push_count - 1; i >= 0; --i) { |
134 instr->AddPushedValue(environment->ExpressionStackAt(i)); | 134 instr->AddPushedValue(environment->ExpressionStackAt(i)); |
135 } | 135 } |
136 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { | 136 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { |
137 int index = environment->assigned_variables()->at(i); | 137 int index = environment->assigned_variables()->at(i); |
138 instr->AddAssignedValue(index, environment->Lookup(index)); | 138 instr->AddAssignedValue(index, environment->Lookup(index)); |
139 } | 139 } |
140 environment->ClearHistory(); | 140 environment->ClearHistory(); |
141 return instr; | 141 return instr; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 | 215 |
216 | 216 |
217 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { | 217 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { |
218 if (!predecessors_.is_empty()) { | 218 if (!predecessors_.is_empty()) { |
219 // Only loop header blocks can have a predecessor added after | 219 // Only loop header blocks can have a predecessor added after |
220 // instructions have been added to the block (they have phis for all | 220 // instructions have been added to the block (they have phis for all |
221 // values in the environment, these phis may be eliminated later). | 221 // values in the environment, these phis may be eliminated later). |
222 ASSERT(IsLoopHeader() || first_ == NULL); | 222 ASSERT(IsLoopHeader() || first_ == NULL); |
223 HEnvironment* incoming_env = pred->last_environment(); | 223 HEnvironment* incoming_env = pred->last_environment(); |
224 if (IsLoopHeader()) { | 224 if (IsLoopHeader()) { |
225 ASSERT(phis()->length() == incoming_env->values()->length()); | 225 ASSERT(phis()->length() == incoming_env->length()); |
226 for (int i = 0; i < phis_.length(); ++i) { | 226 for (int i = 0; i < phis_.length(); ++i) { |
227 phis_[i]->AddInput(incoming_env->values()->at(i)); | 227 phis_[i]->AddInput(incoming_env->values()->at(i)); |
228 } | 228 } |
229 } else { | 229 } else { |
230 last_environment()->AddIncomingEdge(this, pred->last_environment()); | 230 last_environment()->AddIncomingEdge(this, pred->last_environment()); |
231 } | 231 } |
232 } else if (!HasEnvironment() && !IsFinished()) { | 232 } else if (!HasEnvironment() && !IsFinished()) { |
233 ASSERT(!IsLoopHeader()); | 233 ASSERT(!IsLoopHeader()); |
234 SetInitialEnvironment(pred->last_environment()->Copy()); | 234 SetInitialEnvironment(pred->last_environment()->Copy()); |
235 } | 235 } |
(...skipping 1739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1975 } | 1975 } |
1976 } | 1976 } |
1977 | 1977 |
1978 | 1978 |
1979 // Implementation of utility classes to represent an expression's context in | 1979 // Implementation of utility classes to represent an expression's context in |
1980 // the AST. | 1980 // the AST. |
1981 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) | 1981 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) |
1982 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { | 1982 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { |
1983 owner->set_ast_context(this); // Push. | 1983 owner->set_ast_context(this); // Push. |
1984 #ifdef DEBUG | 1984 #ifdef DEBUG |
1985 original_count_ = owner->environment()->total_count(); | 1985 original_length_ = owner->environment()->length(); |
1986 #endif | 1986 #endif |
1987 } | 1987 } |
1988 | 1988 |
1989 | 1989 |
1990 AstContext::~AstContext() { | 1990 AstContext::~AstContext() { |
1991 owner_->set_ast_context(outer_); // Pop. | 1991 owner_->set_ast_context(outer_); // Pop. |
1992 } | 1992 } |
1993 | 1993 |
1994 | 1994 |
1995 EffectContext::~EffectContext() { | 1995 EffectContext::~EffectContext() { |
1996 ASSERT(owner()->HasStackOverflow() || | 1996 ASSERT(owner()->HasStackOverflow() || |
1997 !owner()->subgraph()->HasExit() || | 1997 !owner()->subgraph()->HasExit() || |
1998 owner()->environment()->total_count() == original_count_); | 1998 owner()->environment()->length() == original_length_); |
1999 } | 1999 } |
2000 | 2000 |
2001 | 2001 |
2002 ValueContext::~ValueContext() { | 2002 ValueContext::~ValueContext() { |
2003 ASSERT(owner()->HasStackOverflow() || | 2003 ASSERT(owner()->HasStackOverflow() || |
2004 !owner()->subgraph()->HasExit() || | 2004 !owner()->subgraph()->HasExit() || |
2005 owner()->environment()->total_count() == original_count_ + 1); | 2005 owner()->environment()->length() == original_length_ + 1); |
2006 } | 2006 } |
2007 | 2007 |
2008 | 2008 |
2009 void EffectContext::ReturnValue(HValue* value) { | 2009 void EffectContext::ReturnValue(HValue* value) { |
2010 // The value is simply ignored. | 2010 // The value is simply ignored. |
2011 } | 2011 } |
2012 | 2012 |
2013 | 2013 |
2014 void ValueContext::ReturnValue(HValue* value) { | 2014 void ValueContext::ReturnValue(HValue* value) { |
2015 // The value is tracked in the bailout environment, and communicated | 2015 // The value is tracked in the bailout environment, and communicated |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2336 | 2336 |
2337 // Set the initial values of parameters including "this". "This" has | 2337 // Set the initial values of parameters including "this". "This" has |
2338 // parameter index 0. | 2338 // parameter index 0. |
2339 int count = scope->num_parameters() + 1; | 2339 int count = scope->num_parameters() + 1; |
2340 for (int i = 0; i < count; ++i) { | 2340 for (int i = 0; i < count; ++i) { |
2341 HInstruction* parameter = AddInstruction(new HParameter(i)); | 2341 HInstruction* parameter = AddInstruction(new HParameter(i)); |
2342 environment()->Bind(i, parameter); | 2342 environment()->Bind(i, parameter); |
2343 } | 2343 } |
2344 | 2344 |
2345 // Set the initial values of stack-allocated locals. | 2345 // Set the initial values of stack-allocated locals. |
2346 for (int i = count; i < environment()->values()->length(); ++i) { | 2346 for (int i = count; i < environment()->length(); ++i) { |
2347 environment()->Bind(i, undefined_constant); | 2347 environment()->Bind(i, undefined_constant); |
2348 } | 2348 } |
2349 | 2349 |
2350 // Handle the arguments and arguments shadow variables specially (they do | 2350 // Handle the arguments and arguments shadow variables specially (they do |
2351 // not have declarations). | 2351 // not have declarations). |
2352 if (scope->arguments() != NULL) { | 2352 if (scope->arguments() != NULL) { |
2353 HArgumentsObject* object = new HArgumentsObject; | 2353 HArgumentsObject* object = new HArgumentsObject; |
2354 AddInstruction(object); | 2354 AddInstruction(object); |
2355 graph()->SetArgumentsObject(object); | 2355 graph()->SetArgumentsObject(object); |
2356 environment()->Bind(scope->arguments(), object); | 2356 environment()->Bind(scope->arguments(), object); |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2695 HValue* true_value = graph()->GetConstantTrue(); | 2695 HValue* true_value = graph()->GetConstantTrue(); |
2696 HBranch* branch = new HBranch(non_osr_entry, osr_entry, true_value); | 2696 HBranch* branch = new HBranch(non_osr_entry, osr_entry, true_value); |
2697 exit_block()->Finish(branch); | 2697 exit_block()->Finish(branch); |
2698 | 2698 |
2699 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 2699 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
2700 non_osr_entry->Goto(loop_predecessor); | 2700 non_osr_entry->Goto(loop_predecessor); |
2701 | 2701 |
2702 int osr_entry_id = statement->OsrEntryId(); | 2702 int osr_entry_id = statement->OsrEntryId(); |
2703 // We want the correct environment at the OsrEntry instruction. Build | 2703 // We want the correct environment at the OsrEntry instruction. Build |
2704 // it explicitly. The expression stack should be empty. | 2704 // it explicitly. The expression stack should be empty. |
2705 int count = osr_entry->last_environment()->total_count(); | 2705 int count = osr_entry->last_environment()->length(); |
2706 ASSERT(count == (osr_entry->last_environment()->parameter_count() + | 2706 ASSERT(count == (osr_entry->last_environment()->parameter_count() + |
2707 osr_entry->last_environment()->local_count())); | 2707 osr_entry->last_environment()->local_count())); |
2708 for (int i = 0; i < count; ++i) { | 2708 for (int i = 0; i < count; ++i) { |
2709 HUnknownOSRValue* unknown = new HUnknownOSRValue; | 2709 HUnknownOSRValue* unknown = new HUnknownOSRValue; |
2710 osr_entry->AddInstruction(unknown); | 2710 osr_entry->AddInstruction(unknown); |
2711 osr_entry->last_environment()->Bind(i, unknown); | 2711 osr_entry->last_environment()->Bind(i, unknown); |
2712 } | 2712 } |
2713 | 2713 |
2714 osr_entry->AddSimulate(osr_entry_id); | 2714 osr_entry->AddSimulate(osr_entry_id); |
2715 osr_entry->AddInstruction(new HOsrEntry(osr_entry_id)); | 2715 osr_entry->AddInstruction(new HOsrEntry(osr_entry_id)); |
(...skipping 2556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5272 parameter_count_ = parameter_count; | 5272 parameter_count_ = parameter_count; |
5273 local_count_ = local_count; | 5273 local_count_ = local_count; |
5274 | 5274 |
5275 // Avoid reallocating the temporaries' backing store on the first Push. | 5275 // Avoid reallocating the temporaries' backing store on the first Push. |
5276 int total = parameter_count + local_count + stack_height; | 5276 int total = parameter_count + local_count + stack_height; |
5277 values_.Initialize(total + 4); | 5277 values_.Initialize(total + 4); |
5278 for (int i = 0; i < total; ++i) values_.Add(NULL); | 5278 for (int i = 0; i < total; ++i) values_.Add(NULL); |
5279 } | 5279 } |
5280 | 5280 |
5281 | 5281 |
| 5282 void HEnvironment::Initialize(const HEnvironment* other) { |
| 5283 closure_ = other->closure(); |
| 5284 values_.AddAll(other->values_); |
| 5285 assigned_variables_.AddAll(other->assigned_variables_); |
| 5286 parameter_count_ = other->parameter_count_; |
| 5287 local_count_ = other->local_count_; |
| 5288 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
| 5289 pop_count_ = other->pop_count_; |
| 5290 push_count_ = other->push_count_; |
| 5291 ast_id_ = other->ast_id_; |
| 5292 } |
| 5293 |
| 5294 |
5282 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 5295 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
5283 ASSERT(!block->IsLoopHeader()); | 5296 ASSERT(!block->IsLoopHeader()); |
5284 ASSERT(values_.length() == other->values_.length()); | 5297 ASSERT(values_.length() == other->values_.length()); |
5285 | 5298 |
5286 int length = values_.length(); | 5299 int length = values_.length(); |
5287 for (int i = 0; i < length; ++i) { | 5300 for (int i = 0; i < length; ++i) { |
5288 HValue* value = values_[i]; | 5301 HValue* value = values_[i]; |
5289 if (value != NULL && value->IsPhi() && value->block() == block) { | 5302 if (value != NULL && value->IsPhi() && value->block() == block) { |
5290 // There is already a phi for the i'th value. | 5303 // There is already a phi for the i'th value. |
5291 HPhi* phi = HPhi::cast(value); | 5304 HPhi* phi = HPhi::cast(value); |
(...skipping 10 matching lines...) Expand all Loading... |
5302 phi->AddInput(old_value); | 5315 phi->AddInput(old_value); |
5303 } | 5316 } |
5304 phi->AddInput(other->values_[i]); | 5317 phi->AddInput(other->values_[i]); |
5305 this->values_[i] = phi; | 5318 this->values_[i] = phi; |
5306 block->AddPhi(phi); | 5319 block->AddPhi(phi); |
5307 } | 5320 } |
5308 } | 5321 } |
5309 } | 5322 } |
5310 | 5323 |
5311 | 5324 |
5312 void HEnvironment::Initialize(const HEnvironment* other) { | 5325 void HEnvironment::Bind(int index, HValue* value) { |
5313 closure_ = other->closure(); | 5326 ASSERT(value != NULL); |
5314 values_.AddAll(other->values_); | 5327 if (!assigned_variables_.Contains(index)) { |
5315 assigned_variables_.AddAll(other->assigned_variables_); | 5328 assigned_variables_.Add(index); |
5316 parameter_count_ = other->parameter_count_; | 5329 } |
5317 local_count_ = other->local_count_; | 5330 values_[index] = value; |
5318 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | |
5319 pop_count_ = other->pop_count_; | |
5320 push_count_ = other->push_count_; | |
5321 ast_id_ = other->ast_id_; | |
5322 } | 5331 } |
5323 | 5332 |
5324 | 5333 |
5325 int HEnvironment::IndexFor(Variable* variable) const { | 5334 bool HEnvironment::HasExpressionAt(int index) const { |
5326 Slot* slot = variable->AsSlot(); | 5335 return index >= parameter_count_ + local_count_; |
5327 ASSERT(slot != NULL && slot->IsStackAllocated()); | 5336 } |
5328 if (slot->type() == Slot::PARAMETER) { | 5337 |
5329 return slot->index() + 1; | 5338 |
5330 } else { | 5339 bool HEnvironment::ExpressionStackIsEmpty() const { |
5331 return parameter_count_ + slot->index(); | 5340 int first_expression = parameter_count() + local_count(); |
| 5341 ASSERT(length() >= first_expression); |
| 5342 return length() == first_expression; |
| 5343 } |
| 5344 |
| 5345 |
| 5346 void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { |
| 5347 int count = index_from_top + 1; |
| 5348 int index = values_.length() - count; |
| 5349 ASSERT(HasExpressionAt(index)); |
| 5350 // The push count must include at least the element in question or else |
| 5351 // the new value will not be included in this environment's history. |
| 5352 if (push_count_ < count) { |
| 5353 // This is the same effect as popping then re-pushing 'count' elements. |
| 5354 pop_count_ += (count - push_count_); |
| 5355 push_count_ = count; |
| 5356 } |
| 5357 values_[index] = value; |
| 5358 } |
| 5359 |
| 5360 |
| 5361 void HEnvironment::Drop(int count) { |
| 5362 for (int i = 0; i < count; ++i) { |
| 5363 Pop(); |
5332 } | 5364 } |
5333 } | 5365 } |
5334 | 5366 |
5335 | 5367 |
5336 HEnvironment* HEnvironment::Copy() const { | 5368 HEnvironment* HEnvironment::Copy() const { |
5337 return new HEnvironment(this); | 5369 return new HEnvironment(this); |
5338 } | 5370 } |
5339 | 5371 |
5340 | 5372 |
5341 HEnvironment* HEnvironment::CopyWithoutHistory() const { | 5373 HEnvironment* HEnvironment::CopyWithoutHistory() const { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5386 for (int i = 0; i < local_count; ++i) { | 5418 for (int i = 0; i < local_count; ++i) { |
5387 inner->SetValueAt(local_base + i, undefined); | 5419 inner->SetValueAt(local_base + i, undefined); |
5388 } | 5420 } |
5389 | 5421 |
5390 inner->set_ast_id(function->id()); | 5422 inner->set_ast_id(function->id()); |
5391 return inner; | 5423 return inner; |
5392 } | 5424 } |
5393 | 5425 |
5394 | 5426 |
5395 void HEnvironment::PrintTo(StringStream* stream) { | 5427 void HEnvironment::PrintTo(StringStream* stream) { |
5396 for (int i = 0; i < total_count(); i++) { | 5428 for (int i = 0; i < length(); i++) { |
5397 if (i == 0) stream->Add("parameters\n"); | 5429 if (i == 0) stream->Add("parameters\n"); |
5398 if (i == parameter_count()) stream->Add("locals\n"); | 5430 if (i == parameter_count()) stream->Add("locals\n"); |
5399 if (i == parameter_count() + local_count()) stream->Add("expressions"); | 5431 if (i == parameter_count() + local_count()) stream->Add("expressions"); |
5400 HValue* val = values_.at(i); | 5432 HValue* val = values_.at(i); |
5401 stream->Add("%d: ", i); | 5433 stream->Add("%d: ", i); |
5402 if (val != NULL) { | 5434 if (val != NULL) { |
5403 val->PrintNameTo(stream); | 5435 val->PrintNameTo(stream); |
5404 } else { | 5436 } else { |
5405 stream->Add("NULL"); | 5437 stream->Add("NULL"); |
5406 } | 5438 } |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5694 } | 5726 } |
5695 | 5727 |
5696 #ifdef DEBUG | 5728 #ifdef DEBUG |
5697 if (graph_ != NULL) graph_->Verify(); | 5729 if (graph_ != NULL) graph_->Verify(); |
5698 if (chunk_ != NULL) chunk_->Verify(); | 5730 if (chunk_ != NULL) chunk_->Verify(); |
5699 if (allocator_ != NULL) allocator_->Verify(); | 5731 if (allocator_ != NULL) allocator_->Verify(); |
5700 #endif | 5732 #endif |
5701 } | 5733 } |
5702 | 5734 |
5703 } } // namespace v8::internal | 5735 } } // namespace v8::internal |
OLD | NEW |