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 |