1d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)/* 2d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * Copyright (C) 2014 Google Inc. All rights reserved. 3d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * 4d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 5d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * modification, are permitted provided that the following conditions are 6d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * met: 7d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * 8d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 9d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 10d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 11d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 12d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * in the documentation and/or other materials provided with the 13d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * distribution. 14d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 15d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 16d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * this software without specific prior written permission. 17d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * 18d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 30d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 31d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "config.h" 32d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/PurgeableVector.h" 33d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 34d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/TestingPlatformSupport.h" 35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "public/platform/WebDiscardableMemory.h" 36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/Vector.h" 37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include <algorithm> 39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include <cstdlib> 40d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 41d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include <gtest/gtest.h> 42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)using namespace blink; 44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)namespace { 46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)const size_t kTestSize = 32 * 1024; 48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 49d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)enum DiscardableMemorySupport { 50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) DontSupportDiscardableMemory, 51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) SupportDiscardableMemory, 52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}; 53d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class PurgeableVectorTestWithPlatformSupport : public testing::TestWithParam<DiscardableMemorySupport> { 55d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)public: 56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVectorTestWithPlatformSupport() : m_testingPlatformSupport(makeTestingPlatformSupportConfig()) { } 57d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)protected: 59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) bool isDiscardableMemorySupported() const { return GetParam() == SupportDiscardableMemory; } 60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) TestingPlatformSupport::Config makeTestingPlatformSupportConfig() const 62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) TestingPlatformSupport::Config config; 64d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) config.hasDiscardableMemorySupport = isDiscardableMemorySupported(); 65d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return config; 66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 67d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 68d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector::PurgeableOption makePurgeableOption() const 69d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return isDiscardableMemorySupported() ? PurgeableVector::Purgeable : PurgeableVector::NotPurgeable; 71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 72d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)private: 74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) TestingPlatformSupport m_testingPlatformSupport; 75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}; 76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, grow) 78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.grow(kTestSize); 81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(kTestSize, purgeableVector.size()); 82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Make sure the underlying buffer was actually (re)allocated. 83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) memset(purgeableVector.data(), 0, purgeableVector.size()); 84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 85d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 86d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, clear) 87d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 88d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData(kTestSize); 89d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 90d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 92d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(testData.data(), testData.size()); 93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(testData.size(), purgeableVector.size()); 94d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.clear(); 96d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(0U, purgeableVector.size()); 97d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(0, purgeableVector.data()); 98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 99d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 100d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, clearDoesNotResetLockCounter) 101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.clear(); 104d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_TRUE(purgeableVector.isLocked()); 105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.unlock(); 106d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_FALSE(purgeableVector.isLocked()); 107d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 108d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, reserveCapacityDoesNotChangeSize) 110d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 112d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(0U, purgeableVector.size()); 113d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.reserveCapacity(kTestSize); 114d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(0U, purgeableVector.size()); 115d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 116d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 117d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, multipleAppends) 118d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 119d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData(kTestSize); 120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 121d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 122d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 123d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Force an allocation. 124d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const char kSmallString[] = "hello"; 125d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(kSmallString, sizeof(kSmallString)); 126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const char* const data = purgeableVector.data(); 127d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 128d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Append all the testing data in 4 iterations. The |data| pointer should 129d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // have been changed at the end of the unit test due to reallocations. 130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const size_t kIterationCount = 4; 131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(0U, testData.size() % kIterationCount); 132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (size_t i = 0; i < kIterationCount; ++i) { 133d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const char* const testDataStart = testData.data() + i * (testData.size() / kIterationCount); 134d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(testDataStart, testData.size() / kIterationCount); 135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ((i + 1) * testData.size() / kIterationCount, purgeableVector.size() - sizeof(kSmallString)); 136d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(sizeof(kSmallString) + testData.size(), purgeableVector.size()); 139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_NE(data, purgeableVector.data()); 140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(0, memcmp(purgeableVector.data() + sizeof(kSmallString), testData.data(), testData.size())); 141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 142d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, multipleAppendsAfterReserveCapacity) 144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData(kTestSize); 146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 149d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.reserveCapacity(testData.size()); 150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const char* const data = purgeableVector.data(); 151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // The |data| pointer should be unchanged at the end of the unit test 153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // meaning that there should not have been any reallocation. 154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const size_t kIterationCount = 4; 155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(0U, testData.size() % kIterationCount); 156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (size_t i = 0; i < kIterationCount; ++i) { 157d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const char* const testDataStart = testData.data() + i * (testData.size() / kIterationCount); 158d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(testDataStart, testData.size() / kIterationCount); 159d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ((i + 1) * testData.size() / kIterationCount, purgeableVector.size()); 160d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 161d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 162d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(testData.size(), purgeableVector.size()); 163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(data, purgeableVector.data()); 164d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size())); 165d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 166d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 167d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, reserveCapacityUsesExactCapacityWhenVectorIsEmpty) 168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 169d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData(kTestSize); 170d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 171d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 172d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 173d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.reserveCapacity(kTestSize); 174d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const char* const data = purgeableVector.data(); 175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(testData.data(), testData.size()); 177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(data, purgeableVector.data()); 178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size())); 179d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // This test is not reliable if the PurgeableVector uses a plain WTF::Vector 181d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // for storage, as it does if discardable memory is not supported; the vectors 182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // capacity will always be expanded to fill the PartitionAlloc bucket. 183d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isDiscardableMemorySupported()) { 184d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Appending one extra byte should cause a reallocation since the first 185d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // allocation happened while the purgeable vector was empty. This behavior 186d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // helps us guarantee that there is no memory waste on very small vectors 187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // (which SharedBuffer requires). 188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(testData.data(), 1); 189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_NE(data, purgeableVector.data()); 190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 191d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, appendReservesCapacityIfNeeded) 194d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData(kTestSize); 196d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 197d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 198d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 199d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // No reserveCapacity(). 200d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_FALSE(purgeableVector.data()); 201d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 202d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(testData.data(), testData.size()); 203d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(testData.size(), purgeableVector.size()); 204d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size())); 205d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 206d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 207d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, adopt) 208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 209d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData(kTestSize); 210d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 211d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const Vector<char> testDataCopy(testData); 212d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const char* const testDataPtr = testData.data(); 213d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 214d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.adopt(testData); 216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_TRUE(testData.isEmpty()); 217d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(kTestSize, purgeableVector.size()); 218d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(0, memcmp(purgeableVector.data(), testDataCopy.data(), testDataCopy.size())); 219d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 220d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isDiscardableMemorySupported()) { 221d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // An extra discardable memory allocation + memcpy() should have happened. 222d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_NE(testDataPtr, purgeableVector.data()); 223d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else { 224d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Vector::swap() should have been used. 225d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(testDataPtr, purgeableVector.data()); 226d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 227d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 228d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 229d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, adoptEmptyVector) 230d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 231d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData; 232d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(makePurgeableOption()); 233d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.adopt(testData); 234d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 235d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 236d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST(PurgeableVectorTestWithPlatformSupport, adoptDiscardsPreviousData) 237d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 238d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData; 239d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 240d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 241d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(PurgeableVector::NotPurgeable); 242d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) static const char smallString[] = "hello"; 243d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(smallString, sizeof(smallString)); 244d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(0, memcmp(purgeableVector.data(), smallString, sizeof(smallString))); 245d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 246d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.adopt(testData); 247d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(testData.size(), purgeableVector.size()); 248d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size())); 249d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 250d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 251d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, unlockWithoutHintAtConstruction) 252d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 253d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData(30000); 254d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 255d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 256d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) unsigned length = testData.size(); 257d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(PurgeableVector::NotPurgeable); 258d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(testData.data(), length); 259d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(length, purgeableVector.size()); 260d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const char* data = purgeableVector.data(); 261d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 262d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.unlock(); 263d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 264d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Note that the purgeable vector must be locked before calling data(). 265d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const bool wasPurged = !purgeableVector.lock(); 266d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isDiscardableMemorySupported()) { 267d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // The implementation of purgeable memory used for testing always purges data upon unlock(). 268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_TRUE(wasPurged); 269d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 270d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 271d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isDiscardableMemorySupported()) { 272d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // The data should have been moved from the heap-allocated vector to a purgeable buffer. 273d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_NE(data, purgeableVector.data()); 274d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else { 275d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(data, purgeableVector.data()); 276d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 277d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 278d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!wasPurged) 279d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), length)); 280d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 281d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST(PurgeableVectorTest, unlockOnEmptyPurgeableVector) 283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 284d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector; 285d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(0U, purgeableVector.size()); 286d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.unlock(); 287d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_FALSE(purgeableVector.isLocked()); 288d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 289d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 290d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, unlockOnPurgeableVectorWithPurgeableHint) 291d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 292d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData(kTestSize); 293d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 294d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 295d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector; 296d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(testData.data(), kTestSize); 297d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const char* const data = purgeableVector.data(); 298d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 299d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // unlock() should happen in place, i.e. without causing any reallocation. 300d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Note that the instance must be locked when data() is called. 301d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.unlock(); 302d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_FALSE(purgeableVector.isLocked()); 303d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.lock(); 304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_TRUE(purgeableVector.isLocked()); 305d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) EXPECT_EQ(data, purgeableVector.data()); 306d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TEST_P(PurgeableVectorTestWithPlatformSupport, lockingUsesACounter) 309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Vector<char> testData(kTestSize); 311d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) std::generate(testData.begin(), testData.end(), &std::rand); 312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PurgeableVector purgeableVector(PurgeableVector::NotPurgeable); 314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.append(testData.data(), testData.size()); 315d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(testData.size(), purgeableVector.size()); 316d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 317d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_TRUE(purgeableVector.isLocked()); // SharedBuffer is locked at creation. 318d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_TRUE(purgeableVector.lock()); // Add an extra lock. 319d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_TRUE(purgeableVector.isLocked()); 320d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 321d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.unlock(); 322d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_TRUE(purgeableVector.isLocked()); 323d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 324d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) purgeableVector.unlock(); 325d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_FALSE(purgeableVector.isLocked()); 326d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 327d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (purgeableVector.lock()) 328d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT_EQ(0, memcmp(purgeableVector.data(), testData.data(), testData.size())); 329d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 330d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 331d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// Instantiates all the unit tests using the SharedBufferTestWithPlatformSupport fixture both with 332d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// and without discardable memory support. 333d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)INSTANTIATE_TEST_CASE_P(testsWithPlatformSetUp, PurgeableVectorTestWithPlatformSupport, 334d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ::testing::Values(DontSupportDiscardableMemory, SupportDiscardableMemory)); 335d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 336d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} // namespace 337d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 338