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

Side by Side Diff: src/hydrogen.cc

Issue 5992011: Fix a bug in deoptimization environments. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 11 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-instructions.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 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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698