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;
}