📄 purgeablebuffermac.cpp
字号:
/* * Copyright (C) 2008 Apple 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 APPLE 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 APPLE 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"#ifndef BUILDING_ON_TIGER#include "PurgeableBuffer.h"#include <mach/mach.h>#include <wtf/Assertions.h>namespace WebCore { static const size_t minPurgeableBufferSize = 4096; // one page PurgeableBuffer::PurgeableBuffer(char* data, size_t size) : m_data(data) , m_size(size) , m_purgePriority(PurgeDefault) , m_state(NonVolatile){} PurgeableBuffer::~PurgeableBuffer(){ vm_deallocate(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), m_size);}PurgeableBuffer* PurgeableBuffer::create(const char* data, size_t size){ if (size < minPurgeableBufferSize) return 0; vm_address_t buffer = 0; kern_return_t ret = vm_allocate(mach_task_self(), &buffer, size, VM_FLAGS_PURGABLE | VM_FLAGS_ANYWHERE); ASSERT(ret == KERN_SUCCESS); if (ret != KERN_SUCCESS) return 0; ret = vm_copy(mach_task_self(), reinterpret_cast<vm_address_t>(data), size, buffer); ASSERT(ret == KERN_SUCCESS); if (ret != KERN_SUCCESS) { vm_deallocate(mach_task_self(), buffer, size); return 0; } return new PurgeableBuffer(reinterpret_cast<char*>(buffer), size);}bool PurgeableBuffer::makePurgeable(bool purgeable){ if (purgeable) { if (m_state != NonVolatile) return true; int volatileGroup; if (m_purgePriority == PurgeFirst) volatileGroup = VM_VOLATILE_GROUP_0; else if (m_purgePriority == PurgeMiddle) volatileGroup = VM_VOLATILE_GROUP_4; else volatileGroup = VM_VOLATILE_GROUP_7; int state = VM_PURGABLE_VOLATILE | volatileGroup; // So apparently "purgeable" is the correct spelling and the API here is misspelled. kern_return_t ret = vm_purgable_control(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), VM_PURGABLE_SET_STATE, &state); if (ret != KERN_SUCCESS) { // If that failed we have no clue what state we are in so assume purged. m_state = Purged; return true; } m_state = Volatile; return true; } if (m_state == NonVolatile) return true; if (m_state == Purged) return false; int state = VM_PURGABLE_NONVOLATILE; kern_return_t ret = vm_purgable_control(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), VM_PURGABLE_SET_STATE, &state); if (ret != KERN_SUCCESS) { // If that failed we have no clue what state we are in so assume purged. m_state = Purged; return false; } m_state = state & VM_PURGABLE_EMPTY ? Purged : NonVolatile; return m_state == NonVolatile;} bool PurgeableBuffer::wasPurged() const{ if (m_state == NonVolatile) return false; if (m_state == Purged) return true; int state; kern_return_t ret = vm_purgable_control(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), VM_PURGABLE_GET_STATE, &state); if (ret != KERN_SUCCESS) { // If that failed we have no clue what state we are in so assume purged. m_state = Purged; return true; } if (state & VM_PURGABLE_EMPTY) { m_state = Purged; return true; } return false;}void PurgeableBuffer::setPurgePriority(PurgePriority priority){ if (priority == m_purgePriority) return; m_purgePriority = priority; if (m_state != Volatile) return; m_state = NonVolatile; makePurgeable(true);} const char* PurgeableBuffer::data() const{ ASSERT(m_state == NonVolatile); return m_data;} }#endif // BUILDING_ON_TIGER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -