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; }
void VolatileBuffer::Unlock() { MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!"); if (--mLockCount || OnHeap()) { return; } int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT; DebugOnly<kern_return_t> ret = vm_purgable_control(mach_task_self(), (vm_address_t)mBuf, VM_PURGABLE_SET_STATE, &state); MOZ_ASSERT(ret == KERN_SUCCESS, "Failed to set buffer as purgable"); }
bool VolatileBuffer::Lock(void** aBuf) { MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer"); *aBuf = mBuf; if (++mLockCount > 1 || OnHeap()) { return true; } int state = VM_PURGABLE_NONVOLATILE; kern_return_t ret = vm_purgable_control(mach_task_self(), (vm_address_t)mBuf, VM_PURGABLE_SET_STATE, &state); return ret == KERN_SUCCESS && !(state & VM_PURGABLE_EMPTY); }
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; }