/* * Copyright (C) 2013 Google, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "platform/PurgeableBuffer.h" #include "public/platform/Platform.h" #include "public/platform/WebDiscardableMemory.h" #include namespace WebCore { // WebDiscardableMemory allocations are a limited resource. We only use them // when there's a reasonable amount of memory to be saved by the OS discarding // the memory. static size_t minimumSize = 4 * 4096; PassOwnPtr PurgeableBuffer::create(const char* data, size_t size) { if (size < minimumSize) return nullptr; OwnPtr memory = adoptPtr(blink::Platform::current()->allocateAndLockDiscardableMemory(size)); if (!memory) return nullptr; return adoptPtr(new PurgeableBuffer(memory.release(), data, size)); } PurgeableBuffer::~PurgeableBuffer() { if (m_state == Locked) m_memory->unlock(); } const char* PurgeableBuffer::data() const { ASSERT(m_state == Locked); return static_cast(m_memory->data()); } bool PurgeableBuffer::wasPurged() const { return m_state == Purged; } bool PurgeableBuffer::lock() { ASSERT(m_state == Unlocked); if (!m_memory->lock()) { m_state = Purged; m_memory = nullptr; return false; } m_state = Locked; return true; } void PurgeableBuffer::unlock() { ASSERT(m_state == Locked); m_memory->unlock(); m_state = Unlocked; } PurgeableBuffer::PurgeableBuffer(PassOwnPtr memory, const char* data, size_t size) : m_memory(memory) , m_size(size) , m_state(Locked) { memcpy(m_memory->data(), data, size); } }