OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 | 1499 |
1500 void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) { | 1500 void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) { |
1501 __ pop(rcx); | 1501 __ pop(rcx); |
1502 __ push(rdx); | 1502 __ push(rdx); |
1503 __ push(rax); | 1503 __ push(rax); |
1504 __ push(rcx); | 1504 __ push(rcx); |
1505 } | 1505 } |
1506 | 1506 |
1507 | 1507 |
1508 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { | 1508 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { |
1509 // Input on stack: | 1509 // TAGGED case: |
1510 // rsp[8]: argument (should be number). | 1510 // Input: |
1511 // rsp[0]: return address. | 1511 // rsp[8]: argument (should be number). |
| 1512 // rsp[0]: return address. |
| 1513 // Output: |
| 1514 // rax: tagged double result. |
| 1515 // UNTAGGED case: |
| 1516 // Input:: |
| 1517 // rsp[0]: return address. |
| 1518 // xmm1: untagged double input argument |
| 1519 // Output: |
| 1520 // xmm1: untagged double result. |
| 1521 |
1512 Label runtime_call; | 1522 Label runtime_call; |
1513 Label runtime_call_clear_stack; | 1523 Label runtime_call_clear_stack; |
1514 Label input_not_smi; | 1524 Label skip_cache; |
1515 NearLabel loaded; | 1525 const bool tagged = (argument_type_ == TAGGED); |
1516 // Test that rax is a number. | 1526 if (tagged) { |
1517 __ movq(rax, Operand(rsp, kPointerSize)); | 1527 NearLabel input_not_smi; |
1518 __ JumpIfNotSmi(rax, &input_not_smi); | 1528 NearLabel loaded; |
1519 // Input is a smi. Untag and load it onto the FPU stack. | 1529 // Test that rax is a number. |
1520 // Then load the bits of the double into rbx. | 1530 __ movq(rax, Operand(rsp, kPointerSize)); |
1521 __ SmiToInteger32(rax, rax); | 1531 __ JumpIfNotSmi(rax, &input_not_smi); |
1522 __ subq(rsp, Immediate(kPointerSize)); | 1532 // Input is a smi. Untag and load it onto the FPU stack. |
1523 __ cvtlsi2sd(xmm1, rax); | 1533 // Then load the bits of the double into rbx. |
1524 __ movsd(Operand(rsp, 0), xmm1); | 1534 __ SmiToInteger32(rax, rax); |
1525 __ movq(rbx, xmm1); | 1535 __ subq(rsp, Immediate(kDoubleSize)); |
1526 __ movq(rdx, xmm1); | 1536 __ cvtlsi2sd(xmm1, rax); |
1527 __ fld_d(Operand(rsp, 0)); | 1537 __ movsd(Operand(rsp, 0), xmm1); |
1528 __ addq(rsp, Immediate(kPointerSize)); | 1538 __ movq(rbx, xmm1); |
1529 __ jmp(&loaded); | 1539 __ movq(rdx, xmm1); |
| 1540 __ fld_d(Operand(rsp, 0)); |
| 1541 __ addq(rsp, Immediate(kDoubleSize)); |
| 1542 __ jmp(&loaded); |
1530 | 1543 |
1531 __ bind(&input_not_smi); | 1544 __ bind(&input_not_smi); |
1532 // Check if input is a HeapNumber. | 1545 // Check if input is a HeapNumber. |
1533 __ Move(rbx, Factory::heap_number_map()); | 1546 __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex); |
1534 __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); | 1547 __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); |
1535 __ j(not_equal, &runtime_call); | 1548 __ j(not_equal, &runtime_call); |
1536 // Input is a HeapNumber. Push it on the FPU stack and load its | 1549 // Input is a HeapNumber. Push it on the FPU stack and load its |
1537 // bits into rbx. | 1550 // bits into rbx. |
1538 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); | 1551 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); |
1539 __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset)); | 1552 __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset)); |
1540 __ movq(rdx, rbx); | 1553 __ movq(rdx, rbx); |
1541 __ bind(&loaded); | 1554 |
1542 // ST[0] == double value | 1555 __ bind(&loaded); |
| 1556 } else { // UNTAGGED. |
| 1557 __ movq(rbx, xmm1); |
| 1558 __ movq(rdx, xmm1); |
| 1559 } |
| 1560 |
| 1561 // ST[0] == double value, if TAGGED. |
1543 // rbx = bits of double value. | 1562 // rbx = bits of double value. |
1544 // rdx = also bits of double value. | 1563 // rdx = also bits of double value. |
1545 // Compute hash (h is 32 bits, bits are 64 and the shifts are arithmetic): | 1564 // Compute hash (h is 32 bits, bits are 64 and the shifts are arithmetic): |
1546 // h = h0 = bits ^ (bits >> 32); | 1565 // h = h0 = bits ^ (bits >> 32); |
1547 // h ^= h >> 16; | 1566 // h ^= h >> 16; |
1548 // h ^= h >> 8; | 1567 // h ^= h >> 8; |
1549 // h = h & (cacheSize - 1); | 1568 // h = h & (cacheSize - 1); |
1550 // or h = (h0 ^ (h0 >> 8) ^ (h0 >> 16) ^ (h0 >> 24)) & (cacheSize - 1) | 1569 // or h = (h0 ^ (h0 >> 8) ^ (h0 >> 16) ^ (h0 >> 24)) & (cacheSize - 1) |
1551 __ sar(rdx, Immediate(32)); | 1570 __ sar(rdx, Immediate(32)); |
1552 __ xorl(rdx, rbx); | 1571 __ xorl(rdx, rbx); |
(...skipping 11 matching lines...) Expand all Loading... |
1564 | 1583 |
1565 // ST[0] == double value. | 1584 // ST[0] == double value. |
1566 // rbx = bits of double value. | 1585 // rbx = bits of double value. |
1567 // rcx = TranscendentalCache::hash(double value). | 1586 // rcx = TranscendentalCache::hash(double value). |
1568 __ movq(rax, ExternalReference::transcendental_cache_array_address()); | 1587 __ movq(rax, ExternalReference::transcendental_cache_array_address()); |
1569 // rax points to cache array. | 1588 // rax points to cache array. |
1570 __ movq(rax, Operand(rax, type_ * sizeof(TranscendentalCache::caches_[0]))); | 1589 __ movq(rax, Operand(rax, type_ * sizeof(TranscendentalCache::caches_[0]))); |
1571 // rax points to the cache for the type type_. | 1590 // rax points to the cache for the type type_. |
1572 // If NULL, the cache hasn't been initialized yet, so go through runtime. | 1591 // If NULL, the cache hasn't been initialized yet, so go through runtime. |
1573 __ testq(rax, rax); | 1592 __ testq(rax, rax); |
1574 __ j(zero, &runtime_call_clear_stack); | 1593 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED. |
1575 #ifdef DEBUG | 1594 #ifdef DEBUG |
1576 // Check that the layout of cache elements match expectations. | 1595 // Check that the layout of cache elements match expectations. |
1577 { // NOLINT - doesn't like a single brace on a line. | 1596 { // NOLINT - doesn't like a single brace on a line. |
1578 TranscendentalCache::Element test_elem[2]; | 1597 TranscendentalCache::Element test_elem[2]; |
1579 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); | 1598 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); |
1580 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); | 1599 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); |
1581 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); | 1600 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); |
1582 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); | 1601 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); |
1583 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); | 1602 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); |
1584 // Two uint_32's and a pointer per element. | 1603 // Two uint_32's and a pointer per element. |
1585 CHECK_EQ(16, static_cast<int>(elem2_start - elem_start)); | 1604 CHECK_EQ(16, static_cast<int>(elem2_start - elem_start)); |
1586 CHECK_EQ(0, static_cast<int>(elem_in0 - elem_start)); | 1605 CHECK_EQ(0, static_cast<int>(elem_in0 - elem_start)); |
1587 CHECK_EQ(kIntSize, static_cast<int>(elem_in1 - elem_start)); | 1606 CHECK_EQ(kIntSize, static_cast<int>(elem_in1 - elem_start)); |
1588 CHECK_EQ(2 * kIntSize, static_cast<int>(elem_out - elem_start)); | 1607 CHECK_EQ(2 * kIntSize, static_cast<int>(elem_out - elem_start)); |
1589 } | 1608 } |
1590 #endif | 1609 #endif |
1591 // Find the address of the rcx'th entry in the cache, i.e., &rax[rcx*16]. | 1610 // Find the address of the rcx'th entry in the cache, i.e., &rax[rcx*16]. |
1592 __ addl(rcx, rcx); | 1611 __ addl(rcx, rcx); |
1593 __ lea(rcx, Operand(rax, rcx, times_8, 0)); | 1612 __ lea(rcx, Operand(rax, rcx, times_8, 0)); |
1594 // Check if cache matches: Double value is stored in uint32_t[2] array. | 1613 // Check if cache matches: Double value is stored in uint32_t[2] array. |
1595 NearLabel cache_miss; | 1614 NearLabel cache_miss; |
1596 __ cmpq(rbx, Operand(rcx, 0)); | 1615 __ cmpq(rbx, Operand(rcx, 0)); |
1597 __ j(not_equal, &cache_miss); | 1616 __ j(not_equal, &cache_miss); |
1598 // Cache hit! | 1617 // Cache hit! |
1599 __ movq(rax, Operand(rcx, 2 * kIntSize)); | 1618 __ movq(rax, Operand(rcx, 2 * kIntSize)); |
1600 __ fstp(0); // Clear FPU stack. | 1619 if (tagged) { |
1601 __ ret(kPointerSize); | 1620 __ fstp(0); // Clear FPU stack. |
| 1621 __ ret(kPointerSize); |
| 1622 } else { // UNTAGGED. |
| 1623 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 1624 __ Ret(); |
| 1625 } |
1602 | 1626 |
1603 __ bind(&cache_miss); | 1627 __ bind(&cache_miss); |
1604 // Update cache with new value. | 1628 // Update cache with new value. |
1605 Label nan_result; | 1629 if (tagged) { |
1606 GenerateOperation(masm, &nan_result); | |
1607 __ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack); | 1630 __ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack); |
| 1631 } else { // UNTAGGED. |
| 1632 __ AllocateHeapNumber(rax, rdi, &skip_cache); |
| 1633 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1); |
| 1634 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); |
| 1635 } |
| 1636 GenerateOperation(masm); |
1608 __ movq(Operand(rcx, 0), rbx); | 1637 __ movq(Operand(rcx, 0), rbx); |
1609 __ movq(Operand(rcx, 2 * kIntSize), rax); | 1638 __ movq(Operand(rcx, 2 * kIntSize), rax); |
1610 __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); | 1639 __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); |
1611 __ ret(kPointerSize); | 1640 if (tagged) { |
| 1641 __ ret(kPointerSize); |
| 1642 } else { // UNTAGGED. |
| 1643 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 1644 __ Ret(); |
1612 | 1645 |
1613 __ bind(&runtime_call_clear_stack); | 1646 // Skip cache and return answer directly, only in untagged case. |
1614 __ fstp(0); | 1647 __ bind(&skip_cache); |
1615 __ bind(&runtime_call); | 1648 __ subq(rsp, Immediate(kDoubleSize)); |
1616 __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1); | 1649 __ movsd(Operand(rsp, 0), xmm1); |
| 1650 __ fld_d(Operand(rsp, 0)); |
| 1651 GenerateOperation(masm); |
| 1652 __ fstp_d(Operand(rsp, 0)); |
| 1653 __ movsd(xmm1, Operand(rsp, 0)); |
| 1654 __ addq(rsp, Immediate(kDoubleSize)); |
| 1655 // We return the value in xmm1 without adding it to the cache, but |
| 1656 // we cause a scavenging GC so that future allocations will succeed. |
| 1657 __ EnterInternalFrame(); |
| 1658 // Allocate an unused object bigger than a HeapNumber. |
| 1659 __ Push(Smi::FromInt(2 * kDoubleSize)); |
| 1660 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); |
| 1661 __ LeaveInternalFrame(); |
| 1662 __ Ret(); |
| 1663 } |
1617 | 1664 |
1618 __ bind(&nan_result); | 1665 // Call runtime, doing whatever allocation and cleanup is necessary. |
1619 __ fstp(0); // Remove argument from FPU stack. | 1666 if (tagged) { |
1620 __ LoadRoot(rax, Heap::kNanValueRootIndex); | 1667 __ bind(&runtime_call_clear_stack); |
1621 __ movq(Operand(rcx, 0), rbx); | 1668 __ fstp(0); |
1622 __ movq(Operand(rcx, 2 * kIntSize), rax); | 1669 __ bind(&runtime_call); |
1623 __ ret(kPointerSize); | 1670 __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1); |
| 1671 } else { // UNTAGGED. |
| 1672 __ bind(&runtime_call_clear_stack); |
| 1673 __ bind(&runtime_call); |
| 1674 __ AllocateHeapNumber(rax, rdi, &skip_cache); |
| 1675 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1); |
| 1676 __ EnterInternalFrame(); |
| 1677 __ push(rax); |
| 1678 __ CallRuntime(RuntimeFunction(), 1); |
| 1679 __ LeaveInternalFrame(); |
| 1680 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 1681 __ Ret(); |
| 1682 } |
1624 } | 1683 } |
1625 | 1684 |
1626 | 1685 |
1627 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { | 1686 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { |
1628 switch (type_) { | 1687 switch (type_) { |
1629 // Add more cases when necessary. | 1688 // Add more cases when necessary. |
1630 case TranscendentalCache::SIN: return Runtime::kMath_sin; | 1689 case TranscendentalCache::SIN: return Runtime::kMath_sin; |
1631 case TranscendentalCache::COS: return Runtime::kMath_cos; | 1690 case TranscendentalCache::COS: return Runtime::kMath_cos; |
1632 case TranscendentalCache::LOG: return Runtime::kMath_log; | 1691 case TranscendentalCache::LOG: return Runtime::kMath_log; |
1633 default: | 1692 default: |
1634 UNIMPLEMENTED(); | 1693 UNIMPLEMENTED(); |
1635 return Runtime::kAbort; | 1694 return Runtime::kAbort; |
1636 } | 1695 } |
1637 } | 1696 } |
1638 | 1697 |
1639 | 1698 |
1640 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm, | 1699 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { |
1641 Label* on_nan_result) { | |
1642 // Registers: | 1700 // Registers: |
| 1701 // rax: Newly allocated HeapNumber, which must be preserved. |
1643 // rbx: Bits of input double. Must be preserved. | 1702 // rbx: Bits of input double. Must be preserved. |
1644 // rcx: Pointer to cache entry. Must be preserved. | 1703 // rcx: Pointer to cache entry. Must be preserved. |
1645 // st(0): Input double | 1704 // st(0): Input double |
1646 Label done; | 1705 Label done; |
1647 if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) { | 1706 if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) { |
1648 // Both fsin and fcos require arguments in the range +/-2^63 and | 1707 // Both fsin and fcos require arguments in the range +/-2^63 and |
1649 // return NaN for infinities and NaN. They can share all code except | 1708 // return NaN for infinities and NaN. They can share all code except |
1650 // the actual fsin/fcos operation. | 1709 // the actual fsin/fcos operation. |
1651 Label in_range; | 1710 Label in_range; |
1652 // If argument is outside the range -2^63..2^63, fsin/cos doesn't | 1711 // If argument is outside the range -2^63..2^63, fsin/cos doesn't |
1653 // work. We must reduce it to the appropriate range. | 1712 // work. We must reduce it to the appropriate range. |
1654 __ movq(rdi, rbx); | 1713 __ movq(rdi, rbx); |
1655 // Move exponent and sign bits to low bits. | 1714 // Move exponent and sign bits to low bits. |
1656 __ shr(rdi, Immediate(HeapNumber::kMantissaBits)); | 1715 __ shr(rdi, Immediate(HeapNumber::kMantissaBits)); |
1657 // Remove sign bit. | 1716 // Remove sign bit. |
1658 __ andl(rdi, Immediate((1 << HeapNumber::kExponentBits) - 1)); | 1717 __ andl(rdi, Immediate((1 << HeapNumber::kExponentBits) - 1)); |
1659 int supported_exponent_limit = (63 + HeapNumber::kExponentBias); | 1718 int supported_exponent_limit = (63 + HeapNumber::kExponentBias); |
1660 __ cmpl(rdi, Immediate(supported_exponent_limit)); | 1719 __ cmpl(rdi, Immediate(supported_exponent_limit)); |
1661 __ j(below, &in_range); | 1720 __ j(below, &in_range); |
1662 // Check for infinity and NaN. Both return NaN for sin. | 1721 // Check for infinity and NaN. Both return NaN for sin. |
1663 __ cmpl(rdi, Immediate(0x7ff)); | 1722 __ cmpl(rdi, Immediate(0x7ff)); |
1664 __ j(equal, on_nan_result); | 1723 NearLabel non_nan_result; |
| 1724 __ j(not_equal, &non_nan_result); |
| 1725 // Input is +/-Infinity or NaN. Result is NaN. |
| 1726 __ fstp(0); |
| 1727 __ LoadRoot(kScratchRegister, Heap::kNanValueRootIndex); |
| 1728 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); |
| 1729 __ jmp(&done); |
| 1730 |
| 1731 __ bind(&non_nan_result); |
1665 | 1732 |
1666 // Use fpmod to restrict argument to the range +/-2*PI. | 1733 // Use fpmod to restrict argument to the range +/-2*PI. |
| 1734 __ movq(rdi, rax); // Save rax before using fnstsw_ax. |
1667 __ fldpi(); | 1735 __ fldpi(); |
1668 __ fadd(0); | 1736 __ fadd(0); |
1669 __ fld(1); | 1737 __ fld(1); |
1670 // FPU Stack: input, 2*pi, input. | 1738 // FPU Stack: input, 2*pi, input. |
1671 { | 1739 { |
1672 Label no_exceptions; | 1740 Label no_exceptions; |
1673 __ fwait(); | 1741 __ fwait(); |
1674 __ fnstsw_ax(); | 1742 __ fnstsw_ax(); |
1675 // Clear if Illegal Operand or Zero Division exceptions are set. | 1743 // Clear if Illegal Operand or Zero Division exceptions are set. |
1676 __ testl(rax, Immediate(5)); // #IO and #ZD flags of FPU status word. | 1744 __ testl(rax, Immediate(5)); // #IO and #ZD flags of FPU status word. |
(...skipping 12 matching lines...) Expand all Loading... |
1689 __ testl(rax, Immediate(0x400)); // Check C2 bit of FPU status word. | 1757 __ testl(rax, Immediate(0x400)); // Check C2 bit of FPU status word. |
1690 // If C2 is set, computation only has partial result. Loop to | 1758 // If C2 is set, computation only has partial result. Loop to |
1691 // continue computation. | 1759 // continue computation. |
1692 __ j(not_zero, &partial_remainder_loop); | 1760 __ j(not_zero, &partial_remainder_loop); |
1693 } | 1761 } |
1694 // FPU Stack: input, 2*pi, input % 2*pi | 1762 // FPU Stack: input, 2*pi, input % 2*pi |
1695 __ fstp(2); | 1763 __ fstp(2); |
1696 // FPU Stack: input % 2*pi, 2*pi, | 1764 // FPU Stack: input % 2*pi, 2*pi, |
1697 __ fstp(0); | 1765 __ fstp(0); |
1698 // FPU Stack: input % 2*pi | 1766 // FPU Stack: input % 2*pi |
| 1767 __ movq(rax, rdi); // Restore rax, pointer to the new HeapNumber. |
1699 __ bind(&in_range); | 1768 __ bind(&in_range); |
1700 switch (type_) { | 1769 switch (type_) { |
1701 case TranscendentalCache::SIN: | 1770 case TranscendentalCache::SIN: |
1702 __ fsin(); | 1771 __ fsin(); |
1703 break; | 1772 break; |
1704 case TranscendentalCache::COS: | 1773 case TranscendentalCache::COS: |
1705 __ fcos(); | 1774 __ fcos(); |
1706 break; | 1775 break; |
1707 default: | 1776 default: |
1708 UNREACHABLE(); | 1777 UNREACHABLE(); |
(...skipping 3157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4866 FieldOperand(elements, PixelArray::kExternalPointerOffset)); | 4935 FieldOperand(elements, PixelArray::kExternalPointerOffset)); |
4867 __ movb(Operand(external_pointer, untagged_key, times_1, 0), untagged_value); | 4936 __ movb(Operand(external_pointer, untagged_key, times_1, 0), untagged_value); |
4868 __ ret(0); // Return value in eax. | 4937 __ ret(0); // Return value in eax. |
4869 } | 4938 } |
4870 | 4939 |
4871 #undef __ | 4940 #undef __ |
4872 | 4941 |
4873 } } // namespace v8::internal | 4942 } } // namespace v8::internal |
4874 | 4943 |
4875 #endif // V8_TARGET_ARCH_X64 | 4944 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |