| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1464 Comment cmnt(masm_, "[ WithExitStatement"); | 1464 Comment cmnt(masm_, "[ WithExitStatement"); |
| 1465 CodeForStatementPosition(node); | 1465 CodeForStatementPosition(node); |
| 1466 // Pop context. | 1466 // Pop context. |
| 1467 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); | 1467 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); |
| 1468 // Update context local. | 1468 // Update context local. |
| 1469 __ str(cp, frame_->Context()); | 1469 __ str(cp, frame_->Context()); |
| 1470 ASSERT(frame_->height() == original_height); | 1470 ASSERT(frame_->height() == original_height); |
| 1471 } | 1471 } |
| 1472 | 1472 |
| 1473 | 1473 |
| 1474 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { | |
| 1475 return kFastSwitchMaxOverheadFactor; | |
| 1476 } | |
| 1477 | |
| 1478 int CodeGenerator::FastCaseSwitchMinCaseCount() { | |
| 1479 return kFastSwitchMinCaseCount; | |
| 1480 } | |
| 1481 | |
| 1482 | |
| 1483 void CodeGenerator::GenerateFastCaseSwitchJumpTable( | |
| 1484 SwitchStatement* node, | |
| 1485 int min_index, | |
| 1486 int range, | |
| 1487 Label* default_label, | |
| 1488 Vector<Label*> case_targets, | |
| 1489 Vector<Label> case_labels) { | |
| 1490 VirtualFrame::SpilledScope spilled_scope; | |
| 1491 JumpTarget setup_default; | |
| 1492 JumpTarget is_smi; | |
| 1493 | |
| 1494 // A non-null default label pointer indicates a default case among | |
| 1495 // the case labels. Otherwise we use the break target as a | |
| 1496 // "default" for failure to hit the jump table. | |
| 1497 JumpTarget* default_target = | |
| 1498 (default_label == NULL) ? node->break_target() : &setup_default; | |
| 1499 | |
| 1500 ASSERT(kSmiTag == 0 && kSmiTagSize <= 2); | |
| 1501 frame_->EmitPop(r0); | |
| 1502 | |
| 1503 // Test for a Smi value in a HeapNumber. | |
| 1504 __ tst(r0, Operand(kSmiTagMask)); | |
| 1505 is_smi.Branch(eq); | |
| 1506 __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE); | |
| 1507 default_target->Branch(ne); | |
| 1508 frame_->EmitPush(r0); | |
| 1509 frame_->CallRuntime(Runtime::kNumberToSmi, 1); | |
| 1510 is_smi.Bind(); | |
| 1511 | |
| 1512 if (min_index != 0) { | |
| 1513 // Small positive numbers can be immediate operands. | |
| 1514 if (min_index < 0) { | |
| 1515 // If min_index is Smi::kMinValue, -min_index is not a Smi. | |
| 1516 if (Smi::IsValid(-min_index)) { | |
| 1517 __ add(r0, r0, Operand(Smi::FromInt(-min_index))); | |
| 1518 } else { | |
| 1519 __ add(r0, r0, Operand(Smi::FromInt(-min_index - 1))); | |
| 1520 __ add(r0, r0, Operand(Smi::FromInt(1))); | |
| 1521 } | |
| 1522 } else { | |
| 1523 __ sub(r0, r0, Operand(Smi::FromInt(min_index))); | |
| 1524 } | |
| 1525 } | |
| 1526 __ tst(r0, Operand(0x80000000 | kSmiTagMask)); | |
| 1527 default_target->Branch(ne); | |
| 1528 __ cmp(r0, Operand(Smi::FromInt(range))); | |
| 1529 default_target->Branch(ge); | |
| 1530 VirtualFrame* start_frame = new VirtualFrame(frame_); | |
| 1531 __ SmiJumpTable(r0, case_targets); | |
| 1532 | |
| 1533 GenerateFastCaseSwitchCases(node, case_labels, start_frame); | |
| 1534 | |
| 1535 // If there was a default case among the case labels, we need to | |
| 1536 // emit code to jump to it from the default target used for failure | |
| 1537 // to hit the jump table. | |
| 1538 if (default_label != NULL) { | |
| 1539 if (has_valid_frame()) { | |
| 1540 node->break_target()->Jump(); | |
| 1541 } | |
| 1542 setup_default.Bind(); | |
| 1543 frame_->MergeTo(start_frame); | |
| 1544 __ b(default_label); | |
| 1545 DeleteFrame(); | |
| 1546 } | |
| 1547 if (node->break_target()->is_linked()) { | |
| 1548 node->break_target()->Bind(); | |
| 1549 } | |
| 1550 } | |
| 1551 | |
| 1552 | |
| 1553 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { | 1474 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { |
| 1554 #ifdef DEBUG | 1475 #ifdef DEBUG |
| 1555 int original_height = frame_->height(); | 1476 int original_height = frame_->height(); |
| 1556 #endif | 1477 #endif |
| 1557 VirtualFrame::SpilledScope spilled_scope; | 1478 VirtualFrame::SpilledScope spilled_scope; |
| 1558 Comment cmnt(masm_, "[ SwitchStatement"); | 1479 Comment cmnt(masm_, "[ SwitchStatement"); |
| 1559 CodeForStatementPosition(node); | 1480 CodeForStatementPosition(node); |
| 1560 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); | 1481 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); |
| 1561 | 1482 |
| 1562 LoadAndSpill(node->tag()); | 1483 LoadAndSpill(node->tag()); |
| 1563 if (TryGenerateFastCaseSwitchStatement(node)) { | |
| 1564 ASSERT(!has_valid_frame() || frame_->height() == original_height); | |
| 1565 return; | |
| 1566 } | |
| 1567 | 1484 |
| 1568 JumpTarget next_test; | 1485 JumpTarget next_test; |
| 1569 JumpTarget fall_through; | 1486 JumpTarget fall_through; |
| 1570 JumpTarget default_entry; | 1487 JumpTarget default_entry; |
| 1571 JumpTarget default_exit(JumpTarget::BIDIRECTIONAL); | 1488 JumpTarget default_exit(JumpTarget::BIDIRECTIONAL); |
| 1572 ZoneList<CaseClause*>* cases = node->cases(); | 1489 ZoneList<CaseClause*>* cases = node->cases(); |
| 1573 int length = cases->length(); | 1490 int length = cases->length(); |
| 1574 CaseClause* default_clause = NULL; | 1491 CaseClause* default_clause = NULL; |
| 1575 | 1492 |
| 1576 for (int i = 0; i < length; i++) { | 1493 for (int i = 0; i < length; i++) { |
| (...skipping 4100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5677 __ mov(r2, Operand(0)); | 5594 __ mov(r2, Operand(0)); |
| 5678 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 5595 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
| 5679 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 5596 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
| 5680 RelocInfo::CODE_TARGET); | 5597 RelocInfo::CODE_TARGET); |
| 5681 } | 5598 } |
| 5682 | 5599 |
| 5683 | 5600 |
| 5684 #undef __ | 5601 #undef __ |
| 5685 | 5602 |
| 5686 } } // namespace v8::internal | 5603 } } // namespace v8::internal |
| OLD | NEW |