| Index: src/hydrogen.cc
|
| ===================================================================
|
| --- src/hydrogen.cc (revision 9901)
|
| +++ src/hydrogen.cc (working copy)
|
| @@ -734,7 +734,6 @@
|
| Postorder(it.Current(), visited, order, block);
|
| }
|
| } else {
|
| - ASSERT(block->IsFinished());
|
| for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
|
| Postorder(it.Current(), visited, order, loop_header);
|
| }
|
| @@ -2709,95 +2708,43 @@
|
| return Bailout("SwitchStatement: too many clauses");
|
| }
|
|
|
| - HValue* context = environment()->LookupContext();
|
| -
|
| CHECK_ALIVE(VisitForValue(stmt->tag()));
|
| AddSimulate(stmt->EntryId());
|
| HValue* tag_value = Pop();
|
| HBasicBlock* first_test_block = current_block();
|
|
|
| - SwitchType switch_type = UNKNOWN_SWITCH;
|
| -
|
| - // 1. Extract clause type
|
| + // 1. Build all the tests, with dangling true branches. Unconditionally
|
| + // deoptimize if we encounter a non-smi comparison.
|
| for (int i = 0; i < clause_count; ++i) {
|
| CaseClause* clause = clauses->at(i);
|
| if (clause->is_default()) continue;
|
| -
|
| - if (switch_type == UNKNOWN_SWITCH) {
|
| - if (clause->label()->IsSmiLiteral()) {
|
| - switch_type = SMI_SWITCH;
|
| - } else if (clause->label()->IsStringLiteral()) {
|
| - switch_type = STRING_SWITCH;
|
| - } else {
|
| - return Bailout("SwitchStatement: non-literal switch label");
|
| - }
|
| - } else if ((switch_type == STRING_SWITCH &&
|
| - !clause->label()->IsStringLiteral()) ||
|
| - (switch_type == SMI_SWITCH &&
|
| - !clause->label()->IsSmiLiteral())) {
|
| - return Bailout("SwitchStatemnt: mixed label types are not supported");
|
| + if (!clause->label()->IsSmiLiteral()) {
|
| + return Bailout("SwitchStatement: non-literal switch label");
|
| }
|
| - }
|
|
|
| - HUnaryControlInstruction* string_check = NULL;
|
| - HBasicBlock* not_string_block = NULL;
|
| -
|
| - // Test switch's tag value if all clauses are string literals
|
| - if (switch_type == STRING_SWITCH) {
|
| - string_check = new(zone()) HIsStringAndBranch(tag_value);
|
| - first_test_block = graph()->CreateBasicBlock();
|
| - not_string_block = graph()->CreateBasicBlock();
|
| -
|
| - string_check->SetSuccessorAt(0, first_test_block);
|
| - string_check->SetSuccessorAt(1, not_string_block);
|
| - current_block()->Finish(string_check);
|
| -
|
| - set_current_block(first_test_block);
|
| - }
|
| -
|
| - // 2. Build all the tests, with dangling true branches
|
| - for (int i = 0; i < clause_count; ++i) {
|
| - CaseClause* clause = clauses->at(i);
|
| - if (clause->is_default()) continue;
|
| -
|
| - if (switch_type == SMI_SWITCH) {
|
| - clause->RecordTypeFeedback(oracle());
|
| + // 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;
|
| }
|
|
|
| - // Generate a compare and branch.
|
| + // Otherwise generate a compare and branch.
|
| CHECK_ALIVE(VisitForValue(clause->label()));
|
| HValue* label_value = Pop();
|
| -
|
| - HBasicBlock* next_test_block = graph()->CreateBasicBlock();
|
| + HCompareIDAndBranch* compare =
|
| + new(zone()) HCompareIDAndBranch(tag_value,
|
| + label_value,
|
| + Token::EQ_STRICT);
|
| + compare->SetInputRepresentation(Representation::Integer32());
|
| HBasicBlock* body_block = graph()->CreateBasicBlock();
|
| -
|
| - HControlInstruction* compare;
|
| -
|
| - if (switch_type == SMI_SWITCH) {
|
| - 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;
|
| - }
|
| -
|
| - HCompareIDAndBranch* compare_ =
|
| - new(zone()) HCompareIDAndBranch(tag_value,
|
| - label_value,
|
| - Token::EQ_STRICT);
|
| - compare_->SetInputRepresentation(Representation::Integer32());
|
| - compare = compare_;
|
| - } else {
|
| - compare = new(zone()) HStringCompareAndBranch(context, tag_value,
|
| - label_value,
|
| - Token::EQ_STRICT);
|
| - }
|
| -
|
| + HBasicBlock* next_test_block = graph()->CreateBasicBlock();
|
| compare->SetSuccessorAt(0, body_block);
|
| compare->SetSuccessorAt(1, next_test_block);
|
| current_block()->Finish(compare);
|
| -
|
| set_current_block(next_test_block);
|
| }
|
|
|
| @@ -2805,15 +2752,10 @@
|
| // exit. This block is NULL if we deoptimized.
|
| HBasicBlock* last_block = current_block();
|
|
|
| - if (not_string_block != NULL) {
|
| - last_block = CreateJoin(last_block, not_string_block, stmt->ExitId());
|
| - }
|
| -
|
| - // 3. Loop over the clauses and the linked list of tests in lockstep,
|
| + // 2. Loop over the clauses and the linked list of tests in lockstep,
|
| // translating the clause bodies.
|
| HBasicBlock* curr_test_block = first_test_block;
|
| HBasicBlock* fall_through_block = NULL;
|
| -
|
| BreakAndContinueInfo break_info(stmt);
|
| { BreakAndContinueScope push(&break_info, this);
|
| for (int i = 0; i < clause_count; ++i) {
|
|
|