diff options
Diffstat (limited to 'Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h')
-rw-r--r-- | Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h new file mode 100644 index 000000000..c244015e7 --- /dev/null +++ b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2011 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. + */ + +#ifndef CopiedSpaceInlineMethods_h +#define CopiedSpaceInlineMethods_h + +#include "CopiedBlock.h" +#include "CopiedSpace.h" +#include "Heap.h" +#include "HeapBlock.h" +#include "JSGlobalData.h" +#include <wtf/CheckedBoolean.h> + +namespace JSC { + +inline bool CopiedSpace::contains(CopiedBlock* block) +{ + return !m_blockFilter.ruleOut(reinterpret_cast<Bits>(block)) && m_blockSet.contains(block); +} + +inline bool CopiedSpace::contains(void* ptr, CopiedBlock*& result) +{ + CopiedBlock* block = blockFor(ptr); + if (contains(block)) { + result = block; + return true; + } + block = oversizeBlockFor(ptr); + result = block; + return contains(block); +} + +inline void CopiedSpace::pin(CopiedBlock* block) +{ + block->m_isPinned = true; +} + +inline void CopiedSpace::pinIfNecessary(void* opaquePointer) +{ + // Pointers into the copied space come in the following varieties: + // 1) Pointers to the start of a span of memory. This is the most + // natural though not necessarily the most common. + // 2) Pointers to one value-sized (8 byte) word past the end of + // a span of memory. This currently occurs with semi-butterflies + // and should be fixed soon, once the other half of the + // butterfly lands. + // 3) Pointers to the innards arising from loop induction variable + // optimizations (either manual ones or automatic, by the + // compiler). + // 4) Pointers to the end of a span of memory in arising from + // induction variable optimizations combined with the + // GC-to-compiler contract laid out in the C spec: a pointer to + // the end of a span of memory must be considered to be a + // pointer to that memory. + + EncodedJSValue* pointer = reinterpret_cast<EncodedJSValue*>(opaquePointer); + CopiedBlock* block; + + // Handle (1) and (3). + if (contains(pointer, block)) + pin(block); + + // Handle (4). We don't have to explicitly check and pin the block under this + // pointer because it cannot possibly point to something that cases (1) and + // (3) above or case (2) below wouldn't already catch. + pointer--; + + // Handle (2) + pointer--; + if (contains(pointer, block)) + pin(block); +} + +inline void CopiedSpace::recycleEvacuatedBlock(CopiedBlock* block) +{ + ASSERT(block); + ASSERT(block->canBeRecycled()); + ASSERT(!block->m_isPinned); + { + SpinLockHolder locker(&m_toSpaceLock); + m_blockSet.remove(block); + m_fromSpace->remove(block); + } + m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block)); +} + +inline void CopiedSpace::recycleBorrowedBlock(CopiedBlock* block) +{ + m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block)); + + { + MutexLocker locker(m_loanedBlocksLock); + ASSERT(m_numberOfLoanedBlocks > 0); + ASSERT(m_inCopyingPhase); + m_numberOfLoanedBlocks--; + if (!m_numberOfLoanedBlocks) + m_loanedBlocksCondition.signal(); + } +} + +inline CopiedBlock* CopiedSpace::allocateBlockForCopyingPhase() +{ + ASSERT(m_inCopyingPhase); + CopiedBlock* block = CopiedBlock::createNoZeroFill(m_heap->blockAllocator().allocate<CopiedBlock>()); + + { + MutexLocker locker(m_loanedBlocksLock); + m_numberOfLoanedBlocks++; + } + + ASSERT(!block->dataSize()); + return block; +} + +inline void CopiedSpace::allocateBlock() +{ + if (m_heap->shouldCollect()) + m_heap->collect(Heap::DoNotSweep); + + m_allocator.resetCurrentBlock(); + + CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocate<CopiedBlock>()); + + m_toSpace->push(block); + m_blockFilter.add(reinterpret_cast<Bits>(block)); + m_blockSet.add(block); + m_allocator.setCurrentBlock(block); +} + +inline CheckedBoolean CopiedSpace::tryAllocate(size_t bytes, void** outPtr) +{ + ASSERT(!m_heap->globalData()->isInitializingObject()); + + if (isOversize(bytes) || !m_allocator.tryAllocate(bytes, outPtr)) + return tryAllocateSlowCase(bytes, outPtr); + + ASSERT(*outPtr); + return true; +} + +inline bool CopiedSpace::isOversize(size_t bytes) +{ + return bytes > s_maxAllocationSize; +} + +inline bool CopiedSpace::isPinned(void* ptr) +{ + return blockFor(ptr)->m_isPinned; +} + +inline CopiedBlock* CopiedSpace::oversizeBlockFor(void* ptr) +{ + return reinterpret_cast<CopiedBlock*>(reinterpret_cast<size_t>(ptr) & WTF::pageMask()); +} + +inline CopiedBlock* CopiedSpace::blockFor(void* ptr) +{ + return reinterpret_cast<CopiedBlock*>(reinterpret_cast<size_t>(ptr) & s_blockMask); +} + +} // namespace JSC + +#endif |