Commit 386bc4c2 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Return on the polymorphic hard deopt case to ensure we don't polute phis with...

Return on the polymorphic hard deopt case to ensure we don't polute phis with fake type information.

R=ishell@chromium.org

Review URL: https://codereview.chromium.org/163403003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19359 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 028ff214
...@@ -1043,9 +1043,8 @@ void HGraphBuilder::IfBuilder::End() { ...@@ -1043,9 +1043,8 @@ void HGraphBuilder::IfBuilder::End() {
current = merge_at_join_blocks_; current = merge_at_join_blocks_;
while (current != NULL) { while (current != NULL) {
if (current->deopt_ && current->block_ != NULL) { if (current->deopt_ && current->block_ != NULL) {
builder_->PadEnvironmentForContinuation(current->block_, current->block_->FinishExit(
merge_block); HAbnormalExit::New(builder_->zone(), NULL), RelocInfo::kNoPosition);
builder_->GotoNoSimulate(current->block_, merge_block);
} }
current = current->next_; current = current->next_;
} }
...@@ -1251,38 +1250,9 @@ HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { ...@@ -1251,38 +1250,9 @@ HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
} }
void HGraphBuilder::FinishExitWithHardDeoptimization( void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) {
const char* reason, HBasicBlock* continuation) {
PadEnvironmentForContinuation(current_block(), continuation);
Add<HDeoptimize>(reason, Deoptimizer::EAGER); Add<HDeoptimize>(reason, Deoptimizer::EAGER);
if (graph()->IsInsideNoSideEffectsScope()) { FinishExitCurrentBlock(New<HAbnormalExit>());
GotoNoSimulate(continuation);
} else {
Goto(continuation);
}
}
void HGraphBuilder::PadEnvironmentForContinuation(
HBasicBlock* from,
HBasicBlock* continuation) {
if (continuation->last_environment() != NULL) {
// When merging from a deopt block to a continuation, resolve differences in
// environment by pushing constant 0 and popping extra values so that the
// environments match during the join. Push 0 since it has the most specific
// representation, and will not influence representation inference of the
// phi.
int continuation_env_length = continuation->last_environment()->length();
while (continuation_env_length != from->last_environment()->length()) {
if (continuation_env_length > from->last_environment()->length()) {
from->last_environment()->Push(graph()->GetConstant0());
} else {
from->last_environment()->Pop();
}
}
} else {
ASSERT(continuation->predecessors()->length() == 0);
}
} }
...@@ -5702,11 +5672,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( ...@@ -5702,11 +5672,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
// know about and do not want to handle ones we've never seen. Otherwise // know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC. // use a generic IC.
if (count == types->length() && FLAG_deoptimize_uncommon_cases) { if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
// Because the deopt may be the only path in the polymorphic load, make sure FinishExitWithHardDeoptimization("Uknown map in polymorphic access");
// that the environment stack matches the depth on deopt that it otherwise
// would have had after a successful load.
if (!ast_context()->IsEffect()) Push(graph()->GetConstant0());
FinishExitWithHardDeoptimization("Uknown map in polymorphic access", join);
} else { } else {
HInstruction* instr = BuildNamedGeneric(access_type, object, name, value); HInstruction* instr = BuildNamedGeneric(access_type, object, name, value);
AddInstruction(instr); AddInstruction(instr);
...@@ -6428,10 +6394,14 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( ...@@ -6428,10 +6394,14 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
set_current_block(other_map); set_current_block(other_map);
} }
// Ensure that we visited at least one map above that goes to join. This is
// necessary because FinishExitWithHardDeoptimization does an AbnormalExit
// rather than joining the join block. If this becomes an issue, insert a
// generic access in the case length() == 0.
ASSERT(join->predecessors()->length() > 0);
// Deopt if none of the cases matched. // Deopt if none of the cases matched.
NoObservableSideEffectsScope scope(this); NoObservableSideEffectsScope scope(this);
FinishExitWithHardDeoptimization("Unknown map in polymorphic element access", FinishExitWithHardDeoptimization("Unknown map in polymorphic element access");
join);
set_current_block(join); set_current_block(join);
return access_type == STORE ? NULL : Pop(); return access_type == STORE ? NULL : Pop();
} }
...@@ -6919,12 +6889,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( ...@@ -6919,12 +6889,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
// know about and do not want to handle ones we've never seen. Otherwise // know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC. // use a generic IC.
if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
// Because the deopt may be the only path in the polymorphic call, make sure FinishExitWithHardDeoptimization("Unknown map in polymorphic call");
// that the environment stack matches the depth on deopt that it otherwise
// would have had after a successful call.
Drop(1); // Drop receiver.
if (!ast_context()->IsEffect()) Push(graph()->GetConstant0());
FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join);
} else { } else {
Property* prop = expr->expression()->AsProperty(); Property* prop = expr->expression()->AsProperty();
HInstruction* function = BuildNamedGeneric( HInstruction* function = BuildNamedGeneric(
......
...@@ -1406,8 +1406,7 @@ class HGraphBuilder { ...@@ -1406,8 +1406,7 @@ class HGraphBuilder {
HValue* EnforceNumberType(HValue* number, Type* expected); HValue* EnforceNumberType(HValue* number, Type* expected);
HValue* TruncateToNumber(HValue* value, Type** expected); HValue* TruncateToNumber(HValue* value, Type** expected);
void FinishExitWithHardDeoptimization(const char* reason, void FinishExitWithHardDeoptimization(const char* reason);
HBasicBlock* continuation);
void AddIncrementCounter(StatsCounter* counter); void AddIncrementCounter(StatsCounter* counter);
...@@ -1798,9 +1797,6 @@ class HGraphBuilder { ...@@ -1798,9 +1797,6 @@ class HGraphBuilder {
HValue* mask, HValue* mask,
int current_probe); int current_probe);
void PadEnvironmentForContinuation(HBasicBlock* from,
HBasicBlock* continuation);
template <class I> template <class I>
I* AddInstructionTyped(I* instr) { I* AddInstructionTyped(I* instr) {
return I::cast(AddInstruction(instr)); return I::cast(AddInstruction(instr));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment