X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/heap/BlockAllocator.cpp?ds=sidebyside diff --git a/heap/BlockAllocator.cpp b/heap/BlockAllocator.cpp deleted file mode 100644 index a20ed3e..0000000 --- a/heap/BlockAllocator.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2012 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. AND ITS CONTRIBUTORS ``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 ITS 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 "BlockAllocator.h" - -#include "MarkedBlock.h" -#include - -namespace JSC { - -BlockAllocator::BlockAllocator() - : m_numberOfFreeBlocks(0) - , m_isCurrentlyAllocating(false) - , m_blockFreeingThreadShouldQuit(false) - , m_blockFreeingThread(GCActivityCallback::s_shouldCreateGCTimer ? - createThread(blockFreeingThreadStartFunc, this, "JavaScriptCore::BlockFree") : 0) -{ - ASSERT(m_blockFreeingThread || !GCActivityCallback::s_shouldCreateGCTimer); -} - -BlockAllocator::~BlockAllocator() -{ - releaseFreeBlocks(); - { - MutexLocker locker(m_freeBlockLock); - m_blockFreeingThreadShouldQuit = true; - m_freeBlockCondition.broadcast(); - } - if (GCActivityCallback::s_shouldCreateGCTimer) - waitForThreadCompletion(m_blockFreeingThread); -} - -void BlockAllocator::releaseFreeBlocks() -{ - while (true) { - MarkedBlock* block; - { - MutexLocker locker(m_freeBlockLock); - if (!m_numberOfFreeBlocks) - block = 0; - else { - // FIXME: How do we know this is a MarkedBlock? It could be a CopiedBlock. - block = static_cast(m_freeBlocks.removeHead()); - ASSERT(block); - m_numberOfFreeBlocks--; - } - } - - if (!block) - break; - - MarkedBlock::destroy(block); - } -} - -void BlockAllocator::waitForRelativeTimeWhileHoldingLock(double relative) -{ - if (m_blockFreeingThreadShouldQuit) - return; - m_freeBlockCondition.timedWait(m_freeBlockLock, currentTime() + relative); -} - -void BlockAllocator::waitForRelativeTime(double relative) -{ - // If this returns early, that's fine, so long as it doesn't do it too - // frequently. It would only be a bug if this function failed to return - // when it was asked to do so. - - MutexLocker locker(m_freeBlockLock); - waitForRelativeTimeWhileHoldingLock(relative); -} - -void BlockAllocator::blockFreeingThreadStartFunc(void* blockAllocator) -{ - static_cast(blockAllocator)->blockFreeingThreadMain(); -} - -void BlockAllocator::blockFreeingThreadMain() -{ - while (!m_blockFreeingThreadShouldQuit) { - // Generally wait for one second before scavenging free blocks. This - // may return early, particularly when we're being asked to quit. - waitForRelativeTime(1.0); - if (m_blockFreeingThreadShouldQuit) - break; - - if (m_isCurrentlyAllocating) { - m_isCurrentlyAllocating = false; - continue; - } - - // Now process the list of free blocks. Keep freeing until half of the - // blocks that are currently on the list are gone. Assume that a size_t - // field can be accessed atomically. - size_t currentNumberOfFreeBlocks = m_numberOfFreeBlocks; - if (!currentNumberOfFreeBlocks) - continue; - - size_t desiredNumberOfFreeBlocks = currentNumberOfFreeBlocks / 2; - - while (!m_blockFreeingThreadShouldQuit) { - MarkedBlock* block; - { - MutexLocker locker(m_freeBlockLock); - if (m_numberOfFreeBlocks <= desiredNumberOfFreeBlocks) - block = 0; - else { - // FIXME: How do we know this is a MarkedBlock? It could be a CopiedBlock. - block = static_cast(m_freeBlocks.removeHead()); - ASSERT(block); - m_numberOfFreeBlocks--; - } - } - - if (!block) - break; - - MarkedBlock::destroy(block); - } - } -} - -} // namespace JSC