Reviewers: Vyacheslav Egorov,

Description:
[hydrogen] optimize switch with string clauses

Hydrogen should optimize not only SMI clauses, but clauses with string literals
too.

[email protected]
BUG=
TEST=


Please review this at http://codereview.chromium.org/8373029/

SVN Base: gh:v8/v8@master

Affected files:
  M src/hydrogen.cc


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);
+      compare->SetSuccessorAt(1, next_test_block);
+      current_block()->Finish(compare);
+    }
+
     set_current_block(next_test_block);
   }



--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to