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