summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/heap')
-rw-r--r--Source/JavaScriptCore/heap/Heap.h8
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp14
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.h4
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.cpp26
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.h7
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.cpp17
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.h14
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.cpp7
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.h11
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.cpp17
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.h15
-rw-r--r--Source/JavaScriptCore/heap/SlotVisitor.h16
-rw-r--r--Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h61
13 files changed, 175 insertions, 42 deletions
diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h
index a43be3df0..595e937ce 100644
--- a/Source/JavaScriptCore/heap/Heap.h
+++ b/Source/JavaScriptCore/heap/Heap.h
@@ -183,6 +183,7 @@ namespace JSC {
void* allocateWithDestructor(size_t);
void* allocateWithoutDestructor(size_t);
+ void* allocateStructure();
static const size_t minExtraCost = 256;
static const size_t maxExtraCost = 1024 * 1024;
@@ -367,7 +368,12 @@ namespace JSC {
ASSERT(isValidAllocation(bytes));
return m_objectSpace.allocateWithoutDestructor(bytes);
}
-
+
+ inline void* Heap::allocateStructure()
+ {
+ return m_objectSpace.allocateStructure();
+ }
+
inline CheckedBoolean Heap::tryAllocateStorage(size_t bytes, void** outPtr)
{
return m_storageSpace.tryAllocate(bytes, outPtr);
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
index 8e0c57b6a..7eb57479b 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
@@ -141,8 +141,10 @@ MachineThreads::MachineThreads(Heap* heap)
MachineThreads::~MachineThreads()
{
- if (m_threadSpecific)
- ThreadSpecificKeyDelete(m_threadSpecific);
+ if (m_threadSpecific) {
+ int error = pthread_key_delete(m_threadSpecific);
+ ASSERT_UNUSED(error, !error);
+ }
MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
for (Thread* t = m_registeredThreads; t;) {
@@ -179,17 +181,19 @@ void MachineThreads::makeUsableFromMultipleThreads()
if (m_threadSpecific)
return;
- ThreadSpecificKeyCreate(&m_threadSpecific, removeThread);
+ int error = pthread_key_create(&m_threadSpecific, removeThread);
+ if (error)
+ CRASH();
}
void MachineThreads::addCurrentThread()
{
ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread());
- if (!m_threadSpecific || ThreadSpecificGet(m_threadSpecific))
+ if (!m_threadSpecific || pthread_getspecific(m_threadSpecific))
return;
- ThreadSpecificSet(m_threadSpecific, this);
+ pthread_setspecific(m_threadSpecific, this);
Thread* thread = new Thread(getCurrentPlatformThread(), wtfThreadData().stack().origin());
MutexLocker lock(m_registeredThreadsMutex);
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.h b/Source/JavaScriptCore/heap/MachineStackMarker.h
index 3d4aa22d4..5c7705fcf 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.h
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.h
@@ -22,8 +22,8 @@
#ifndef MachineThreads_h
#define MachineThreads_h
+#include <pthread.h>
#include <wtf/Noncopyable.h>
-#include <wtf/ThreadSpecific.h>
#include <wtf/ThreadingPrimitives.h>
namespace JSC {
@@ -55,7 +55,7 @@ namespace JSC {
Heap* m_heap;
Mutex m_registeredThreadsMutex;
Thread* m_registeredThreads;
- WTF::ThreadSpecificKey m_threadSpecific;
+ pthread_key_t m_threadSpecific;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp
index 9c679b0ed..02a13077d 100644
--- a/Source/JavaScriptCore/heap/MarkStack.cpp
+++ b/Source/JavaScriptCore/heap/MarkStack.cpp
@@ -35,6 +35,7 @@
#include "JSCell.h"
#include "JSObject.h"
#include "ScopeChain.h"
+#include "SlotVisitorInlineMethods.h"
#include "Structure.h"
#include "UString.h"
#include "WriteBarrier.h"
@@ -518,28 +519,25 @@ void SlotVisitor::startCopying()
ASSERT(!m_copiedAllocator.isValid());
}
-void* SlotVisitor::allocateNewSpace(void* ptr, size_t bytes)
+void* SlotVisitor::allocateNewSpaceSlow(size_t bytes)
{
- if (CopiedSpace::isOversize(bytes)) {
- m_shared.m_copiedSpace->pin(CopiedSpace::oversizeBlockFor(ptr));
- return 0;
- }
-
- if (m_shared.m_copiedSpace->isPinned(ptr))
- return 0;
-
- void* result = 0; // Compilers don't realize that this will be assigned.
- if (m_copiedAllocator.tryAllocate(bytes, &result))
- return result;
-
m_shared.m_copiedSpace->doneFillingBlock(m_copiedAllocator.resetCurrentBlock());
m_copiedAllocator.setCurrentBlock(m_shared.m_copiedSpace->allocateBlockForCopyingPhase());
+ void* result = 0;
CheckedBoolean didSucceed = m_copiedAllocator.tryAllocate(bytes, &result);
ASSERT(didSucceed);
return result;
}
+void* SlotVisitor::allocateNewSpaceOrPin(void* ptr, size_t bytes)
+{
+ if (!checkIfShouldCopyAndPinOtherwise(ptr, bytes))
+ return 0;
+
+ return allocateNewSpace(bytes);
+}
+
ALWAYS_INLINE bool JSString::tryHashConstLock()
{
#if ENABLE(PARALLEL_GC)
@@ -616,7 +614,7 @@ ALWAYS_INLINE void MarkStack::internalAppend(JSValue* slot)
void SlotVisitor::copyAndAppend(void** ptr, size_t bytes, JSValue* values, unsigned length)
{
void* oldPtr = *ptr;
- void* newPtr = allocateNewSpace(oldPtr, bytes);
+ void* newPtr = allocateNewSpaceOrPin(oldPtr, bytes);
if (newPtr) {
size_t jsValuesOffset = static_cast<size_t>(reinterpret_cast<char*>(values) - static_cast<char*>(oldPtr));
diff --git a/Source/JavaScriptCore/heap/MarkStack.h b/Source/JavaScriptCore/heap/MarkStack.h
index ff25531a4..467a5bf46 100644
--- a/Source/JavaScriptCore/heap/MarkStack.h
+++ b/Source/JavaScriptCore/heap/MarkStack.h
@@ -253,6 +253,7 @@ namespace JSC {
template<typename T>
void appendUnbarrieredPointer(T**);
+ void appendUnbarrieredValue(JSValue*);
void addOpaqueRoot(void*);
bool containsOpaqueRoot(void*);
@@ -453,6 +454,12 @@ namespace JSC {
internalAppend(*slot);
}
+ ALWAYS_INLINE void MarkStack::appendUnbarrieredValue(JSValue* slot)
+ {
+ ASSERT(slot);
+ internalAppend(*slot);
+ }
+
ALWAYS_INLINE void MarkStack::append(JSCell** slot)
{
ASSERT(slot);
diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.cpp b/Source/JavaScriptCore/heap/MarkedAllocator.cpp
index 972728637..465e3a72a 100644
--- a/Source/JavaScriptCore/heap/MarkedAllocator.cpp
+++ b/Source/JavaScriptCore/heap/MarkedAllocator.cpp
@@ -29,15 +29,19 @@ bool MarkedAllocator::isPagedOut(double deadline)
inline void* MarkedAllocator::tryAllocateHelper()
{
if (!m_freeList.head) {
- for (MarkedBlock*& block = m_currentBlock; block; block = static_cast<MarkedBlock*>(block->next())) {
+ for (MarkedBlock*& block = m_blocksToSweep; block; block = static_cast<MarkedBlock*>(block->next())) {
m_freeList = block->sweep(MarkedBlock::SweepToFreeList);
- if (m_freeList.head)
+ if (m_freeList.head) {
+ m_currentBlock = block;
break;
+ }
block->didConsumeFreeList();
}
- if (!m_freeList.head)
+ if (!m_freeList.head) {
+ m_currentBlock = 0;
return 0;
+ }
}
MarkedBlock::FreeCell* head = m_freeList.head;
@@ -92,7 +96,7 @@ void* MarkedAllocator::allocateSlowCase()
MarkedBlock* MarkedAllocator::allocateBlock()
{
- MarkedBlock* block = MarkedBlock::create(m_heap->blockAllocator().allocate(), m_heap, m_cellSize, m_cellsNeedDestruction);
+ MarkedBlock* block = MarkedBlock::create(m_heap->blockAllocator().allocate(), m_heap, m_cellSize, m_cellsNeedDestruction, m_onlyContainsStructures);
m_markedSpace->didAddBlock(block);
return block;
}
@@ -100,10 +104,11 @@ MarkedBlock* MarkedAllocator::allocateBlock()
void MarkedAllocator::addBlock(MarkedBlock* block)
{
ASSERT(!m_currentBlock);
+ ASSERT(!m_blocksToSweep);
ASSERT(!m_freeList.head);
m_blockList.append(block);
- m_currentBlock = block;
+ m_blocksToSweep = m_currentBlock = block;
m_freeList = block->sweep(MarkedBlock::SweepToFreeList);
}
@@ -113,6 +118,8 @@ void MarkedAllocator::removeBlock(MarkedBlock* block)
m_currentBlock = static_cast<MarkedBlock*>(m_currentBlock->next());
m_freeList = MarkedBlock::FreeList();
}
+ if (m_blocksToSweep == block)
+ m_blocksToSweep = static_cast<MarkedBlock*>(m_blocksToSweep->next());
m_blockList.remove(block);
}
diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.h b/Source/JavaScriptCore/heap/MarkedAllocator.h
index 8b3620f08..47bae9451 100644
--- a/Source/JavaScriptCore/heap/MarkedAllocator.h
+++ b/Source/JavaScriptCore/heap/MarkedAllocator.h
@@ -24,6 +24,7 @@ public:
void zapFreeList();
size_t cellSize() { return m_cellSize; }
bool cellsNeedDestruction() { return m_cellsNeedDestruction; }
+ bool onlyContainsStructures() { return m_onlyContainsStructures; }
void* allocate();
Heap* heap() { return m_heap; }
@@ -31,7 +32,7 @@ public:
void addBlock(MarkedBlock*);
void removeBlock(MarkedBlock*);
- void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction);
+ void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);
bool isPagedOut(double deadline);
@@ -45,28 +46,33 @@ private:
MarkedBlock::FreeList m_freeList;
MarkedBlock* m_currentBlock;
+ MarkedBlock* m_blocksToSweep;
DoublyLinkedList<HeapBlock> m_blockList;
size_t m_cellSize;
bool m_cellsNeedDestruction;
+ bool m_onlyContainsStructures;
Heap* m_heap;
MarkedSpace* m_markedSpace;
};
inline MarkedAllocator::MarkedAllocator()
: m_currentBlock(0)
+ , m_blocksToSweep(0)
, m_cellSize(0)
, m_cellsNeedDestruction(true)
+ , m_onlyContainsStructures(false)
, m_heap(0)
, m_markedSpace(0)
{
}
-inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction)
+inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
{
m_heap = heap;
m_markedSpace = markedSpace;
m_cellSize = cellSize;
m_cellsNeedDestruction = cellsNeedDestruction;
+ m_onlyContainsStructures = onlyContainsStructures;
}
inline void* MarkedAllocator::allocate()
@@ -82,7 +88,9 @@ inline void* MarkedAllocator::allocate()
inline void MarkedAllocator::reset()
{
- m_currentBlock = static_cast<MarkedBlock*>(m_blockList.head());
+ m_currentBlock = 0;
+ m_freeList = MarkedBlock::FreeList();
+ m_blocksToSweep = static_cast<MarkedBlock*>(m_blockList.head());
}
inline void MarkedAllocator::zapFreeList()
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.cpp b/Source/JavaScriptCore/heap/MarkedBlock.cpp
index 01e4237cb..8ede87927 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.cpp
+++ b/Source/JavaScriptCore/heap/MarkedBlock.cpp
@@ -32,9 +32,9 @@
namespace JSC {
-MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction)
+MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
{
- return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction);
+ return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction, onlyContainsStructures);
}
PageAllocationAligned MarkedBlock::destroy(MarkedBlock* block)
@@ -46,11 +46,12 @@ PageAllocationAligned MarkedBlock::destroy(MarkedBlock* block)
return allocation;
}
-MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction)
+MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
: HeapBlock(allocation)
, m_atomsPerCell((cellSize + atomSize - 1) / atomSize)
, m_endAtom(atomsPerBlock - m_atomsPerCell + 1)
, m_cellsNeedDestruction(cellsNeedDestruction)
+ , m_onlyContainsStructures(onlyContainsStructures)
, m_state(New) // All cells start out unmarked.
, m_weakSet(heap)
{
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h
index c3c43752b..ff7840632 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.h
+++ b/Source/JavaScriptCore/heap/MarkedBlock.h
@@ -113,7 +113,7 @@ namespace JSC {
ReturnType m_count;
};
- static MarkedBlock* create(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction);
+ static MarkedBlock* create(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);
static PageAllocationAligned destroy(MarkedBlock*);
static bool isAtomAligned(const void*);
@@ -145,6 +145,7 @@ namespace JSC {
size_t cellSize();
bool cellsNeedDestruction();
+ bool onlyContainsStructures();
size_t size();
size_t capacity();
@@ -195,7 +196,7 @@ namespace JSC {
typedef char Atom[atomSize];
- MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction);
+ MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);
Atom* atoms();
size_t atomNumber(const void*);
void callDestructor(JSCell*);
@@ -213,6 +214,7 @@ namespace JSC {
WTF::Bitmap<atomsPerBlock, WTF::BitmapNotAtomic> m_marks;
#endif
bool m_cellsNeedDestruction;
+ bool m_onlyContainsStructures;
BlockState m_state;
WeakSet m_weakSet;
};
@@ -322,6 +324,11 @@ namespace JSC {
return m_cellsNeedDestruction;
}
+ inline bool MarkedBlock::onlyContainsStructures()
+ {
+ return m_onlyContainsStructures;
+ }
+
inline size_t MarkedBlock::size()
{
return markCount() * cellSize();
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.cpp b/Source/JavaScriptCore/heap/MarkedSpace.cpp
index a742d8d9a..a9e9ef64d 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.cpp
+++ b/Source/JavaScriptCore/heap/MarkedSpace.cpp
@@ -80,14 +80,16 @@ MarkedSpace::MarkedSpace(Heap* heap)
: m_heap(heap)
{
for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
- allocatorFor(cellSize).init(heap, this, cellSize, false);
- destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
+ allocatorFor(cellSize).init(heap, this, cellSize, false, false);
+ destructorAllocatorFor(cellSize).init(heap, this, cellSize, true, false);
}
for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
- allocatorFor(cellSize).init(heap, this, cellSize, false);
- destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
+ allocatorFor(cellSize).init(heap, this, cellSize, false, false);
+ destructorAllocatorFor(cellSize).init(heap, this, cellSize, true, false);
}
+
+ m_structureAllocator.init(heap, this, WTF::roundUpToMultipleOf(32, sizeof(Structure)), true, true);
}
MarkedSpace::~MarkedSpace()
@@ -117,6 +119,8 @@ void MarkedSpace::resetAllocators()
allocatorFor(cellSize).reset();
destructorAllocatorFor(cellSize).reset();
}
+
+ m_structureAllocator.reset();
}
void MarkedSpace::visitWeakSets(HeapRootVisitor& heapRootVisitor)
@@ -141,6 +145,8 @@ void MarkedSpace::canonicalizeCellLivenessData()
allocatorFor(cellSize).zapFreeList();
destructorAllocatorFor(cellSize).zapFreeList();
}
+
+ m_structureAllocator.zapFreeList();
}
bool MarkedSpace::isPagedOut(double deadline)
@@ -155,6 +161,9 @@ bool MarkedSpace::isPagedOut(double deadline)
return true;
}
+ if (m_structureAllocator.isPagedOut(deadline))
+ return true;
+
return false;
}
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.h b/Source/JavaScriptCore/heap/MarkedSpace.h
index 62d4e5d9e..d2a0688f1 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.h
+++ b/Source/JavaScriptCore/heap/MarkedSpace.h
@@ -80,7 +80,8 @@ public:
MarkedAllocator& destructorAllocatorFor(size_t);
void* allocateWithDestructor(size_t);
void* allocateWithoutDestructor(size_t);
-
+ void* allocateStructure();
+
void resetAllocators();
void visitWeakSets(HeapRootVisitor&);
@@ -132,6 +133,7 @@ private:
Subspace m_destructorSpace;
Subspace m_normalSpace;
+ MarkedAllocator m_structureAllocator;
Heap* m_heap;
MarkedBlockSet m_blocks;
@@ -168,8 +170,12 @@ inline MarkedAllocator& MarkedSpace::allocatorFor(size_t bytes)
inline MarkedAllocator& MarkedSpace::allocatorFor(MarkedBlock* block)
{
+ if (block->onlyContainsStructures())
+ return m_structureAllocator;
+
if (block->cellsNeedDestruction())
return destructorAllocatorFor(block->cellSize());
+
return allocatorFor(block->cellSize());
}
@@ -191,6 +197,11 @@ inline void* MarkedSpace::allocateWithDestructor(size_t bytes)
return destructorAllocatorFor(bytes).allocate();
}
+inline void* MarkedSpace::allocateStructure()
+{
+ return m_structureAllocator.allocate();
+}
+
template <typename Functor> inline typename Functor::ReturnType MarkedSpace::forEachBlock(Functor& functor)
{
for (size_t i = 0; i < preciseCount; ++i) {
@@ -203,6 +214,8 @@ template <typename Functor> inline typename Functor::ReturnType MarkedSpace::for
m_destructorSpace.impreciseAllocators[i].forEachBlock(functor);
}
+ m_structureAllocator.forEachBlock(functor);
+
return functor.returnValue();
}
diff --git a/Source/JavaScriptCore/heap/SlotVisitor.h b/Source/JavaScriptCore/heap/SlotVisitor.h
index d16602f15..a31e88c08 100644
--- a/Source/JavaScriptCore/heap/SlotVisitor.h
+++ b/Source/JavaScriptCore/heap/SlotVisitor.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 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
@@ -62,11 +62,23 @@ public:
void finalizeUnconditionalFinalizers();
void startCopying();
+
+ // High-level API for copying, appropriate for cases where the object's heap references
+ // fall into a contiguous region of the storage chunk and if the object for which you're
+ // doing copying does not occur frequently.
void copyAndAppend(void**, size_t, JSValue*, unsigned);
+
+ // Low-level API for copying, appropriate for cases where the object's heap references
+ // are discontiguous or if the object occurs frequently enough that you need to focus on
+ // performance. Use this with care as it is easy to shoot yourself in the foot.
+ bool checkIfShouldCopyAndPinOtherwise(void* oldPtr, size_t);
+ void* allocateNewSpace(size_t);
+
void doneCopying();
private:
- void* allocateNewSpace(void*, size_t);
+ void* allocateNewSpaceOrPin(void*, size_t);
+ void* allocateNewSpaceSlow(size_t);
void donateKnownParallel();
diff --git a/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h b/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h
new file mode 100644
index 000000000..f02564e10
--- /dev/null
+++ b/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#ifndef SlotVisitorInlineMethods_h
+#define SlotVisitorInlineMethods_h
+
+#include "CopiedSpaceInlineMethods.h"
+#include "SlotVisitor.h"
+
+namespace JSC {
+
+ALWAYS_INLINE bool SlotVisitor::checkIfShouldCopyAndPinOtherwise(void* oldPtr, size_t bytes)
+{
+ if (CopiedSpace::isOversize(bytes)) {
+ m_shared.m_copiedSpace->pin(CopiedSpace::oversizeBlockFor(oldPtr));
+ return false;
+ }
+
+ if (m_shared.m_copiedSpace->isPinned(oldPtr))
+ return false;
+
+ return true;
+}
+
+ALWAYS_INLINE void* SlotVisitor::allocateNewSpace(size_t bytes)
+{
+ void* result = 0; // Compilers don't realize that this will be assigned.
+ if (LIKELY(m_copiedAllocator.tryAllocate(bytes, &result)))
+ return result;
+
+ result = allocateNewSpaceSlow(bytes);
+ ASSERT(result);
+ return result;
+}
+
+} // namespace JSC
+
+#endif // SlotVisitorInlineMethods_h
+