| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 1666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1677 partitionFreeGeneric(genericAllocator.root(), ptr7); | 1677 partitionFreeGeneric(genericAllocator.root(), ptr7); |
| 1678 | 1678 |
| 1679 TestShutdown(); | 1679 TestShutdown(); |
| 1680 } | 1680 } |
| 1681 | 1681 |
| 1682 // Tests the API to purge discardable memory. | 1682 // Tests the API to purge discardable memory. |
| 1683 TEST(PartitionAllocTest, PurgeDiscardable) | 1683 TEST(PartitionAllocTest, PurgeDiscardable) |
| 1684 { | 1684 { |
| 1685 TestSetup(); | 1685 TestSetup(); |
| 1686 | 1686 |
| 1687 // Free the second of two 4096 byte allocations and then purge. |
| 1687 { | 1688 { |
| 1688 void* ptr1 = partitionAllocGeneric(genericAllocator.root(), kSystemPageS
ize - kExtraAllocSize); | 1689 void* ptr1 = partitionAllocGeneric(genericAllocator.root(), kSystemPageS
ize - kExtraAllocSize); |
| 1689 char* ptr2 = reinterpret_cast<char*>(partitionAllocGeneric(genericAlloca
tor.root(), kSystemPageSize - kExtraAllocSize)); | 1690 char* ptr2 = reinterpret_cast<char*>(partitionAllocGeneric(genericAlloca
tor.root(), kSystemPageSize - kExtraAllocSize)); |
| 1690 partitionFreeGeneric(genericAllocator.root(), ptr2); | 1691 partitionFreeGeneric(genericAllocator.root(), ptr2); |
| 1692 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerA
djust(ptr1)); |
| 1693 EXPECT_EQ(2u, page->numUnprovisionedSlots); |
| 1691 { | 1694 { |
| 1692 MockPartitionStatsDumper mockStatsDumperGeneric; | 1695 MockPartitionStatsDumper mockStatsDumperGeneric; |
| 1693 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all
ocator", &mockStatsDumperGeneric); | 1696 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all
ocator", &mockStatsDumperGeneric); |
| 1694 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); | 1697 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); |
| 1695 | 1698 |
| 1696 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get
BucketStats(kSystemPageSize); | 1699 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get
BucketStats(kSystemPageSize); |
| 1697 EXPECT_TRUE(stats); | 1700 EXPECT_TRUE(stats); |
| 1698 EXPECT_TRUE(stats->isValid); | 1701 EXPECT_TRUE(stats->isValid); |
| 1699 EXPECT_EQ(0u, stats->decommittableBytes); | 1702 EXPECT_EQ(0u, stats->decommittableBytes); |
| 1700 EXPECT_EQ(kSystemPageSize, stats->discardableBytes); | 1703 EXPECT_EQ(kSystemPageSize, stats->discardableBytes); |
| 1701 EXPECT_EQ(kSystemPageSize, stats->activeBytes); | 1704 EXPECT_EQ(kSystemPageSize, stats->activeBytes); |
| 1702 EXPECT_EQ(2 * kSystemPageSize, stats->residentBytes); | 1705 EXPECT_EQ(2 * kSystemPageSize, stats->residentBytes); |
| 1703 } | 1706 } |
| 1704 CheckPageInCore(ptr2 - kPointerOffset, true); | 1707 CheckPageInCore(ptr2 - kPointerOffset, true); |
| 1705 partitionPurgeMemoryGeneric(genericAllocator.root(), PartitionPurgeDisca
rdUnusedSystemPages); | 1708 partitionPurgeMemoryGeneric(genericAllocator.root(), PartitionPurgeDisca
rdUnusedSystemPages); |
| 1706 CheckPageInCore(ptr2 - kPointerOffset, false); | 1709 CheckPageInCore(ptr2 - kPointerOffset, false); |
| 1710 EXPECT_EQ(3u, page->numUnprovisionedSlots); |
| 1707 | 1711 |
| 1708 partitionFreeGeneric(genericAllocator.root(), ptr1); | 1712 partitionFreeGeneric(genericAllocator.root(), ptr1); |
| 1709 } | 1713 } |
| 1714 // Free the first of two 4096 byte allocations and then purge. |
| 1715 { |
| 1716 char* ptr1 = reinterpret_cast<char*>(partitionAllocGeneric(genericAlloca
tor.root(), kSystemPageSize - kExtraAllocSize)); |
| 1717 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), kSystemPageS
ize - kExtraAllocSize); |
| 1718 partitionFreeGeneric(genericAllocator.root(), ptr1); |
| 1719 { |
| 1720 MockPartitionStatsDumper mockStatsDumperGeneric; |
| 1721 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all
ocator", &mockStatsDumperGeneric); |
| 1722 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); |
| 1723 |
| 1724 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get
BucketStats(kSystemPageSize); |
| 1725 EXPECT_TRUE(stats); |
| 1726 EXPECT_TRUE(stats->isValid); |
| 1727 EXPECT_EQ(0u, stats->decommittableBytes); |
| 1728 EXPECT_EQ(kSystemPageSize, stats->discardableBytes); |
| 1729 EXPECT_EQ(kSystemPageSize, stats->activeBytes); |
| 1730 EXPECT_EQ(2 * kSystemPageSize, stats->residentBytes); |
| 1731 } |
| 1732 CheckPageInCore(ptr1 - kPointerOffset, true); |
| 1733 partitionPurgeMemoryGeneric(genericAllocator.root(), PartitionPurgeDisca
rdUnusedSystemPages); |
| 1734 CheckPageInCore(ptr1 - kPointerOffset, false); |
| 1735 |
| 1736 partitionFreeGeneric(genericAllocator.root(), ptr2); |
| 1737 } |
| 1710 { | 1738 { |
| 1711 char* ptr1 = reinterpret_cast<char*>(partitionAllocGeneric(genericAlloca
tor.root(), 9216 - kExtraAllocSize)); | 1739 char* ptr1 = reinterpret_cast<char*>(partitionAllocGeneric(genericAlloca
tor.root(), 9216 - kExtraAllocSize)); |
| 1712 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), 9216 - kExtr
aAllocSize); | 1740 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), 9216 - kExtr
aAllocSize); |
| 1713 void* ptr3 = partitionAllocGeneric(genericAllocator.root(), 9216 - kExtr
aAllocSize); | 1741 void* ptr3 = partitionAllocGeneric(genericAllocator.root(), 9216 - kExtr
aAllocSize); |
| 1714 void* ptr4 = partitionAllocGeneric(genericAllocator.root(), 9216 - kExtr
aAllocSize); | 1742 void* ptr4 = partitionAllocGeneric(genericAllocator.root(), 9216 - kExtr
aAllocSize); |
| 1715 memset(ptr1, 'A', 9216 - kExtraAllocSize); | 1743 memset(ptr1, 'A', 9216 - kExtraAllocSize); |
| 1716 memset(ptr2, 'A', 9216 - kExtraAllocSize); | 1744 memset(ptr2, 'A', 9216 - kExtraAllocSize); |
| 1717 partitionFreeGeneric(genericAllocator.root(), ptr2); | 1745 partitionFreeGeneric(genericAllocator.root(), ptr2); |
| 1718 partitionFreeGeneric(genericAllocator.root(), ptr1); | 1746 partitionFreeGeneric(genericAllocator.root(), ptr1); |
| 1719 { | 1747 { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1767 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 62), true); | 1795 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 62), true); |
| 1768 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 63), true); | 1796 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 63), true); |
| 1769 partitionPurgeMemoryGeneric(genericAllocator.root(), PartitionPurgeDisca
rdUnusedSystemPages); | 1797 partitionPurgeMemoryGeneric(genericAllocator.root(), PartitionPurgeDisca
rdUnusedSystemPages); |
| 1770 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 60), true); | 1798 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 60), true); |
| 1771 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 61), false); | 1799 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 61), false); |
| 1772 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 62), false); | 1800 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 62), false); |
| 1773 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 63), false); | 1801 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 63), false); |
| 1774 | 1802 |
| 1775 partitionFreeGeneric(genericAllocator.root(), ptr1); | 1803 partitionFreeGeneric(genericAllocator.root(), ptr1); |
| 1776 } | 1804 } |
| 1805 // This sub-test tests truncation of the provisioned slots in a trickier |
| 1806 // case where the freelist is rewritten. |
| 1807 partitionPurgeMemoryGeneric(genericAllocator.root(), PartitionPurgeDecommitE
mptyPages); |
| 1808 { |
| 1809 char* ptr1 = reinterpret_cast<char*>(partitionAllocGeneric(genericAlloca
tor.root(), kSystemPageSize - kExtraAllocSize)); |
| 1810 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), kSystemPageS
ize - kExtraAllocSize); |
| 1811 void* ptr3 = partitionAllocGeneric(genericAllocator.root(), kSystemPageS
ize - kExtraAllocSize); |
| 1812 void* ptr4 = partitionAllocGeneric(genericAllocator.root(), kSystemPageS
ize - kExtraAllocSize); |
| 1813 ptr1[0] = 'A'; |
| 1814 ptr1[kSystemPageSize] = 'A'; |
| 1815 ptr1[kSystemPageSize * 2] = 'A'; |
| 1816 ptr1[kSystemPageSize * 3] = 'A'; |
| 1817 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerA
djust(ptr1)); |
| 1818 partitionFreeGeneric(genericAllocator.root(), ptr2); |
| 1819 partitionFreeGeneric(genericAllocator.root(), ptr4); |
| 1820 partitionFreeGeneric(genericAllocator.root(), ptr1); |
| 1821 EXPECT_EQ(0u, page->numUnprovisionedSlots); |
| 1822 |
| 1823 { |
| 1824 MockPartitionStatsDumper mockStatsDumperGeneric; |
| 1825 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all
ocator", &mockStatsDumperGeneric); |
| 1826 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); |
| 1827 |
| 1828 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get
BucketStats(kSystemPageSize); |
| 1829 EXPECT_TRUE(stats); |
| 1830 EXPECT_TRUE(stats->isValid); |
| 1831 EXPECT_EQ(0u, stats->decommittableBytes); |
| 1832 EXPECT_EQ(2 * kSystemPageSize, stats->discardableBytes); |
| 1833 EXPECT_EQ(kSystemPageSize, stats->activeBytes); |
| 1834 EXPECT_EQ(4 * kSystemPageSize, stats->residentBytes); |
| 1835 } |
| 1836 CheckPageInCore(ptr1 - kPointerOffset, true); |
| 1837 CheckPageInCore(ptr1 - kPointerOffset + kSystemPageSize, true); |
| 1838 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 2), true); |
| 1839 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 3), true); |
| 1840 partitionPurgeMemoryGeneric(genericAllocator.root(), PartitionPurgeDisca
rdUnusedSystemPages); |
| 1841 EXPECT_EQ(1u, page->numUnprovisionedSlots); |
| 1842 CheckPageInCore(ptr1 - kPointerOffset, true); |
| 1843 CheckPageInCore(ptr1 - kPointerOffset + kSystemPageSize, false); |
| 1844 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 2), true); |
| 1845 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 3), false); |
| 1846 |
| 1847 // Let's check we didn't brick the freelist. |
| 1848 void* ptr1b = partitionAllocGeneric(genericAllocator.root(), kSystemPage
Size - kExtraAllocSize); |
| 1849 EXPECT_EQ(ptr1, ptr1b); |
| 1850 void* ptr2b = partitionAllocGeneric(genericAllocator.root(), kSystemPage
Size - kExtraAllocSize); |
| 1851 EXPECT_EQ(ptr2, ptr2b); |
| 1852 EXPECT_FALSE(page->freelistHead); |
| 1853 |
| 1854 partitionFreeGeneric(genericAllocator.root(), ptr1); |
| 1855 partitionFreeGeneric(genericAllocator.root(), ptr2); |
| 1856 partitionFreeGeneric(genericAllocator.root(), ptr3); |
| 1857 } |
| 1858 // This sub-test is similar, but tests a double-truncation. |
| 1859 partitionPurgeMemoryGeneric(genericAllocator.root(), PartitionPurgeDecommitE
mptyPages); |
| 1860 { |
| 1861 char* ptr1 = reinterpret_cast<char*>(partitionAllocGeneric(genericAlloca
tor.root(), kSystemPageSize - kExtraAllocSize)); |
| 1862 void* ptr2 = partitionAllocGeneric(genericAllocator.root(), kSystemPageS
ize - kExtraAllocSize); |
| 1863 void* ptr3 = partitionAllocGeneric(genericAllocator.root(), kSystemPageS
ize - kExtraAllocSize); |
| 1864 void* ptr4 = partitionAllocGeneric(genericAllocator.root(), kSystemPageS
ize - kExtraAllocSize); |
| 1865 ptr1[0] = 'A'; |
| 1866 ptr1[kSystemPageSize] = 'A'; |
| 1867 ptr1[kSystemPageSize * 2] = 'A'; |
| 1868 ptr1[kSystemPageSize * 3] = 'A'; |
| 1869 PartitionPage* page = partitionPointerToPage(partitionCookieFreePointerA
djust(ptr1)); |
| 1870 partitionFreeGeneric(genericAllocator.root(), ptr4); |
| 1871 partitionFreeGeneric(genericAllocator.root(), ptr3); |
| 1872 EXPECT_EQ(0u, page->numUnprovisionedSlots); |
| 1873 |
| 1874 { |
| 1875 MockPartitionStatsDumper mockStatsDumperGeneric; |
| 1876 partitionDumpStatsGeneric(genericAllocator.root(), "mock_generic_all
ocator", &mockStatsDumperGeneric); |
| 1877 EXPECT_TRUE(mockStatsDumperGeneric.IsMemoryAllocationRecorded()); |
| 1878 |
| 1879 const PartitionBucketMemoryStats* stats = mockStatsDumperGeneric.Get
BucketStats(kSystemPageSize); |
| 1880 EXPECT_TRUE(stats); |
| 1881 EXPECT_TRUE(stats->isValid); |
| 1882 EXPECT_EQ(0u, stats->decommittableBytes); |
| 1883 EXPECT_EQ(2 * kSystemPageSize, stats->discardableBytes); |
| 1884 EXPECT_EQ(2 * kSystemPageSize, stats->activeBytes); |
| 1885 EXPECT_EQ(4 * kSystemPageSize, stats->residentBytes); |
| 1886 } |
| 1887 CheckPageInCore(ptr1 - kPointerOffset, true); |
| 1888 CheckPageInCore(ptr1 - kPointerOffset + kSystemPageSize, true); |
| 1889 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 2), true); |
| 1890 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 3), true); |
| 1891 partitionPurgeMemoryGeneric(genericAllocator.root(), PartitionPurgeDisca
rdUnusedSystemPages); |
| 1892 EXPECT_EQ(2u, page->numUnprovisionedSlots); |
| 1893 CheckPageInCore(ptr1 - kPointerOffset, true); |
| 1894 CheckPageInCore(ptr1 - kPointerOffset + kSystemPageSize, true); |
| 1895 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 2), false); |
| 1896 CheckPageInCore(ptr1 - kPointerOffset + (kSystemPageSize * 3), false); |
| 1897 |
| 1898 EXPECT_FALSE(page->freelistHead); |
| 1899 |
| 1900 partitionFreeGeneric(genericAllocator.root(), ptr1); |
| 1901 partitionFreeGeneric(genericAllocator.root(), ptr2); |
| 1902 } |
| 1777 | 1903 |
| 1778 TestShutdown(); | 1904 TestShutdown(); |
| 1779 } | 1905 } |
| 1780 | 1906 |
| 1781 // Tests that the countLeadingZeros() functions work to our satisfaction. | 1907 // Tests that the countLeadingZeros() functions work to our satisfaction. |
| 1782 // It doesn't seem worth the overhead of a whole new file for these tests, so | 1908 // It doesn't seem worth the overhead of a whole new file for these tests, so |
| 1783 // we'll put them here since partitionAllocGeneric will depend heavily on these | 1909 // we'll put them here since partitionAllocGeneric will depend heavily on these |
| 1784 // functions working correctly. | 1910 // functions working correctly. |
| 1785 TEST(PartitionAllocTest, CLZWorks) | 1911 TEST(PartitionAllocTest, CLZWorks) |
| 1786 { | 1912 { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1799 EXPECT_EQ(32u, countLeadingZerosSizet(0u)); | 1925 EXPECT_EQ(32u, countLeadingZerosSizet(0u)); |
| 1800 EXPECT_EQ(31u, countLeadingZerosSizet(1u)); | 1926 EXPECT_EQ(31u, countLeadingZerosSizet(1u)); |
| 1801 EXPECT_EQ(1u, countLeadingZerosSizet(1u << 30)); | 1927 EXPECT_EQ(1u, countLeadingZerosSizet(1u << 30)); |
| 1802 EXPECT_EQ(0u, countLeadingZerosSizet(1u << 31)); | 1928 EXPECT_EQ(0u, countLeadingZerosSizet(1u << 31)); |
| 1803 #endif | 1929 #endif |
| 1804 } | 1930 } |
| 1805 | 1931 |
| 1806 } // namespace WTF | 1932 } // namespace WTF |
| 1807 | 1933 |
| 1808 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 1934 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| OLD | NEW |