Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 0b843bd45b32eb6d57c1efa86ee784c59290c817..5d83dad92383e779b1285f22ea89e9a94e463180 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -2695,33 +2695,39 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { |
for (int i = 0; i < clause_count; ++i) { |
CaseClause* clause = clauses->at(i); |
if (clause->is_default()) continue; |
- if (!clause->label()->IsSmiLiteral()) { |
+ if (!clause->label()->IsSmiLiteral() && |
+ !clause->label()->IsStringLiteral()) { |
return Bailout("SwitchStatement: non-literal switch label"); |
} |
- // Unconditionally deoptimize on the first non-smi compare. |
clause->RecordTypeFeedback(oracle()); |
- if (!clause->IsSmiCompare()) { |
- // Finish with deoptimize and add uses of enviroment values to |
- // account for invisible uses. |
- current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
- set_current_block(NULL); |
- break; |
- } |
- // Otherwise generate a compare and branch. |
+ // Generate a compare and branch. |
CHECK_ALIVE(VisitForValue(clause->label())); |
HValue* label_value = Pop(); |
- HCompareIDAndBranch* compare = |
- new(zone()) HCompareIDAndBranch(tag_value, |
- label_value, |
- Token::EQ_STRICT); |
- compare->SetInputRepresentation(Representation::Integer32()); |
- HBasicBlock* body_block = graph()->CreateBasicBlock(); |
+ |
HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
- compare->SetSuccessorAt(0, body_block); |
- compare->SetSuccessorAt(1, next_test_block); |
- current_block()->Finish(compare); |
+ HBasicBlock* body_block = graph()->CreateBasicBlock(); |
+ |
+ if (clause->IsSmiCompare()) { |
+ HCompareIDAndBranch* compare = |
+ new(zone()) HCompareIDAndBranch(tag_value, |
+ label_value, |
+ Token::EQ_STRICT); |
+ compare->SetInputRepresentation(Representation::Integer32()); |
+ compare->SetSuccessorAt(0, body_block); |
+ compare->SetSuccessorAt(1, next_test_block); |
+ current_block()->Finish(compare); |
+ } else { |
+ AddInstruction(new(zone()) HCheckNonSmi(tag_value)); |
+ AddInstruction(HCheckInstanceType::NewIsSymbol(tag_value)); |
+ HCompareObjectEqAndBranch* compare = |
+ new(zone()) HCompareObjectEqAndBranch(tag_value, label_value); |
+ compare->SetSuccessorAt(0, body_block); |
Vyacheslav Egorov (Chromium)
2011/10/24 09:37:19
Can be moved outside of the if to avoid code dupli
|
+ compare->SetSuccessorAt(1, next_test_block); |
+ current_block()->Finish(compare); |
+ } |
+ |
set_current_block(next_test_block); |
} |