| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 break; | 1439 break; |
| 1440 } | 1440 } |
| 1441 if (answer_object == Heap::undefined_value()) { | 1441 if (answer_object == Heap::undefined_value()) { |
| 1442 return false; | 1442 return false; |
| 1443 } | 1443 } |
| 1444 frame_->Push(Handle<Object>(answer_object)); | 1444 frame_->Push(Handle<Object>(answer_object)); |
| 1445 return true; | 1445 return true; |
| 1446 } | 1446 } |
| 1447 | 1447 |
| 1448 | 1448 |
| 1449 static void CheckTwoForSminess(MacroAssembler* masm, | 1449 void CodeGenerator::JumpIfNotBothSmiUsingTypeInfo(Register left, |
| 1450 Register left, Register right, Register scratch, | 1450 Register right, |
| 1451 TypeInfo left_info, TypeInfo right_info, | 1451 Register scratch, |
| 1452 DeferredInlineBinaryOperation* deferred); | 1452 TypeInfo left_info, |
| 1453 TypeInfo right_info, |
| 1454 DeferredCode* deferred) { |
| 1455 if (left.is(right)) { |
| 1456 if (!left_info.IsSmi()) { |
| 1457 __ test(left, Immediate(kSmiTagMask)); |
| 1458 deferred->Branch(not_zero); |
| 1459 } else { |
| 1460 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
| 1461 } |
| 1462 } else if (!left_info.IsSmi()) { |
| 1463 if (!right_info.IsSmi()) { |
| 1464 __ mov(scratch, left); |
| 1465 __ or_(scratch, Operand(right)); |
| 1466 __ test(scratch, Immediate(kSmiTagMask)); |
| 1467 deferred->Branch(not_zero); |
| 1468 } else { |
| 1469 __ test(left, Immediate(kSmiTagMask)); |
| 1470 deferred->Branch(not_zero); |
| 1471 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
| 1472 } |
| 1473 } else { |
| 1474 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
| 1475 if (!right_info.IsSmi()) { |
| 1476 __ test(right, Immediate(kSmiTagMask)); |
| 1477 deferred->Branch(not_zero); |
| 1478 } else { |
| 1479 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
| 1480 } |
| 1481 } |
| 1482 } |
| 1453 | 1483 |
| 1454 | 1484 |
| 1455 // Implements a binary operation using a deferred code object and some | 1485 // Implements a binary operation using a deferred code object and some |
| 1456 // inline code to operate on smis quickly. | 1486 // inline code to operate on smis quickly. |
| 1457 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, | 1487 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, |
| 1458 Result* left, | 1488 Result* left, |
| 1459 Result* right, | 1489 Result* right, |
| 1460 OverwriteMode overwrite_mode) { | 1490 OverwriteMode overwrite_mode) { |
| 1461 // Copy the type info because left and right may be overwritten. | 1491 // Copy the type info because left and right may be overwritten. |
| 1462 TypeInfo left_type_info = left->type_info(); | 1492 TypeInfo left_type_info = left->type_info(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1532 | 1562 |
| 1533 // Check that left and right are smi tagged. | 1563 // Check that left and right are smi tagged. |
| 1534 DeferredInlineBinaryOperation* deferred = | 1564 DeferredInlineBinaryOperation* deferred = |
| 1535 new DeferredInlineBinaryOperation(op, | 1565 new DeferredInlineBinaryOperation(op, |
| 1536 (op == Token::DIV) ? eax : edx, | 1566 (op == Token::DIV) ? eax : edx, |
| 1537 left->reg(), | 1567 left->reg(), |
| 1538 right->reg(), | 1568 right->reg(), |
| 1539 left_type_info, | 1569 left_type_info, |
| 1540 right_type_info, | 1570 right_type_info, |
| 1541 overwrite_mode); | 1571 overwrite_mode); |
| 1542 if (left->reg().is(right->reg())) { | 1572 JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(), edx, |
| 1543 __ test(left->reg(), Immediate(kSmiTagMask)); | 1573 left_type_info, right_type_info, deferred); |
| 1544 } else { | 1574 if (!left_is_in_eax) { |
| 1545 // Use the quotient register as a scratch for the tag check. | 1575 __ mov(eax, left->reg()); |
| 1546 if (!left_is_in_eax) __ mov(eax, left->reg()); | |
| 1547 left_is_in_eax = false; // About to destroy the value in eax. | |
| 1548 __ or_(eax, Operand(right->reg())); | |
| 1549 ASSERT(kSmiTag == 0); // Adjust test if not the case. | |
| 1550 __ test(eax, Immediate(kSmiTagMask)); | |
| 1551 } | 1576 } |
| 1552 deferred->Branch(not_zero); | |
| 1553 | |
| 1554 if (!left_is_in_eax) __ mov(eax, left->reg()); | |
| 1555 // Sign extend eax into edx:eax. | 1577 // Sign extend eax into edx:eax. |
| 1556 __ cdq(); | 1578 __ cdq(); |
| 1557 // Check for 0 divisor. | 1579 // Check for 0 divisor. |
| 1558 __ test(right->reg(), Operand(right->reg())); | 1580 __ test(right->reg(), Operand(right->reg())); |
| 1559 deferred->Branch(zero); | 1581 deferred->Branch(zero); |
| 1560 // Divide edx:eax by the right operand. | 1582 // Divide edx:eax by the right operand. |
| 1561 __ idiv(right->reg()); | 1583 __ idiv(right->reg()); |
| 1562 | 1584 |
| 1563 // Complete the operation. | 1585 // Complete the operation. |
| 1564 if (op == Token::DIV) { | 1586 if (op == Token::DIV) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1667 Factory::heap_number_map()); | 1689 Factory::heap_number_map()); |
| 1668 deferred->Branch(not_equal); | 1690 deferred->Branch(not_equal); |
| 1669 | 1691 |
| 1670 // Load integer value into answer register using truncation. | 1692 // Load integer value into answer register using truncation. |
| 1671 __ cvttsd2si(answer.reg(), | 1693 __ cvttsd2si(answer.reg(), |
| 1672 FieldOperand(answer.reg(), HeapNumber::kValueOffset)); | 1694 FieldOperand(answer.reg(), HeapNumber::kValueOffset)); |
| 1673 // Branch if we do not fit in a smi. | 1695 // Branch if we do not fit in a smi. |
| 1674 __ cmp(answer.reg(), 0xc0000000); | 1696 __ cmp(answer.reg(), 0xc0000000); |
| 1675 deferred->Branch(negative); | 1697 deferred->Branch(negative); |
| 1676 } else { | 1698 } else { |
| 1677 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), | 1699 JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(), answer.reg(), |
| 1678 left_type_info, right_type_info, deferred); | 1700 left_type_info, right_type_info, deferred); |
| 1679 | 1701 |
| 1680 // Untag both operands. | 1702 // Untag both operands. |
| 1681 __ mov(answer.reg(), left->reg()); | 1703 __ mov(answer.reg(), left->reg()); |
| 1682 __ SmiUntag(answer.reg()); | 1704 __ SmiUntag(answer.reg()); |
| 1683 } | 1705 } |
| 1684 | 1706 |
| 1685 __ bind(&do_op); | 1707 __ bind(&do_op); |
| 1686 __ SmiUntag(ecx); | 1708 __ SmiUntag(ecx); |
| 1687 // Perform the operation. | 1709 // Perform the operation. |
| 1688 switch (op) { | 1710 switch (op) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1744 | 1766 |
| 1745 // Perform the smi tag check. | 1767 // Perform the smi tag check. |
| 1746 DeferredInlineBinaryOperation* deferred = | 1768 DeferredInlineBinaryOperation* deferred = |
| 1747 new DeferredInlineBinaryOperation(op, | 1769 new DeferredInlineBinaryOperation(op, |
| 1748 answer.reg(), | 1770 answer.reg(), |
| 1749 left->reg(), | 1771 left->reg(), |
| 1750 right->reg(), | 1772 right->reg(), |
| 1751 left_type_info, | 1773 left_type_info, |
| 1752 right_type_info, | 1774 right_type_info, |
| 1753 overwrite_mode); | 1775 overwrite_mode); |
| 1754 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), | 1776 JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(), answer.reg(), |
| 1755 left_type_info, right_type_info, deferred); | 1777 left_type_info, right_type_info, deferred); |
| 1756 | 1778 |
| 1757 __ mov(answer.reg(), left->reg()); | 1779 __ mov(answer.reg(), left->reg()); |
| 1758 switch (op) { | 1780 switch (op) { |
| 1759 case Token::ADD: | 1781 case Token::ADD: |
| 1760 __ add(answer.reg(), Operand(right->reg())); | 1782 __ add(answer.reg(), Operand(right->reg())); |
| 1761 deferred->Branch(overflow); | 1783 deferred->Branch(overflow); |
| 1762 break; | 1784 break; |
| 1763 | 1785 |
| 1764 case Token::SUB: | 1786 case Token::SUB: |
| 1765 __ sub(answer.reg(), Operand(right->reg())); | 1787 __ sub(answer.reg(), Operand(right->reg())); |
| (...skipping 7203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8969 } | 8991 } |
| 8970 ASSERT(frame()->height() == original_height - 3); | 8992 ASSERT(frame()->height() == original_height - 3); |
| 8971 return result; | 8993 return result; |
| 8972 } | 8994 } |
| 8973 | 8995 |
| 8974 | 8996 |
| 8975 #undef __ | 8997 #undef __ |
| 8976 #define __ ACCESS_MASM(masm) | 8998 #define __ ACCESS_MASM(masm) |
| 8977 | 8999 |
| 8978 | 9000 |
| 8979 static void CheckTwoForSminess(MacroAssembler* masm, | |
| 8980 Register left, Register right, Register scratch, | |
| 8981 TypeInfo left_info, TypeInfo right_info, | |
| 8982 DeferredInlineBinaryOperation* deferred) { | |
| 8983 if (left.is(right)) { | |
| 8984 if (!left_info.IsSmi()) { | |
| 8985 __ test(left, Immediate(kSmiTagMask)); | |
| 8986 deferred->Branch(not_zero); | |
| 8987 } else { | |
| 8988 if (FLAG_debug_code) __ AbortIfNotSmi(left); | |
| 8989 } | |
| 8990 } else if (!left_info.IsSmi()) { | |
| 8991 if (!right_info.IsSmi()) { | |
| 8992 __ mov(scratch, left); | |
| 8993 __ or_(scratch, Operand(right)); | |
| 8994 __ test(scratch, Immediate(kSmiTagMask)); | |
| 8995 deferred->Branch(not_zero); | |
| 8996 } else { | |
| 8997 __ test(left, Immediate(kSmiTagMask)); | |
| 8998 deferred->Branch(not_zero); | |
| 8999 if (FLAG_debug_code) __ AbortIfNotSmi(right); | |
| 9000 } | |
| 9001 } else { | |
| 9002 if (FLAG_debug_code) __ AbortIfNotSmi(left); | |
| 9003 if (!right_info.IsSmi()) { | |
| 9004 __ test(right, Immediate(kSmiTagMask)); | |
| 9005 deferred->Branch(not_zero); | |
| 9006 } else { | |
| 9007 if (FLAG_debug_code) __ AbortIfNotSmi(right); | |
| 9008 } | |
| 9009 } | |
| 9010 } | |
| 9011 | |
| 9012 | |
| 9013 Handle<String> Reference::GetName() { | 9001 Handle<String> Reference::GetName() { |
| 9014 ASSERT(type_ == NAMED); | 9002 ASSERT(type_ == NAMED); |
| 9015 Property* property = expression_->AsProperty(); | 9003 Property* property = expression_->AsProperty(); |
| 9016 if (property == NULL) { | 9004 if (property == NULL) { |
| 9017 // Global variable reference treated as a named property reference. | 9005 // Global variable reference treated as a named property reference. |
| 9018 VariableProxy* proxy = expression_->AsVariableProxy(); | 9006 VariableProxy* proxy = expression_->AsVariableProxy(); |
| 9019 ASSERT(proxy->AsVariable() != NULL); | 9007 ASSERT(proxy->AsVariable() != NULL); |
| 9020 ASSERT(proxy->AsVariable()->is_global()); | 9008 ASSERT(proxy->AsVariable()->is_global()); |
| 9021 return proxy->name(); | 9009 return proxy->name(); |
| 9022 } else { | 9010 } else { |
| (...skipping 4689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13712 masm.GetCode(&desc); | 13700 masm.GetCode(&desc); |
| 13713 // Call the function from C++. | 13701 // Call the function from C++. |
| 13714 return FUNCTION_CAST<MemCopyFunction>(buffer); | 13702 return FUNCTION_CAST<MemCopyFunction>(buffer); |
| 13715 } | 13703 } |
| 13716 | 13704 |
| 13717 #undef __ | 13705 #undef __ |
| 13718 | 13706 |
| 13719 } } // namespace v8::internal | 13707 } } // namespace v8::internal |
| 13720 | 13708 |
| 13721 #endif // V8_TARGET_ARCH_IA32 | 13709 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |