#ifndef BlockAllocator_h
#define BlockAllocator_h
+#include "GCActivityCallback.h"
#include "HeapBlock.h"
#include "Region.h"
+#include <condition_variable>
#include <wtf/DoublyLinkedList.h>
#include <wtf/Forward.h>
#include <wtf/PageAllocationAligned.h>
#include <wtf/TCSpinLock.h>
#include <wtf/Threading.h>
-#if PLATFORM(IOS)
-#include "GCActivityCallback.h"
-#endif
-
namespace JSC {
class BlockAllocator;
+class CodeBlock;
class CopiedBlock;
class CopyWorkListSegment;
+template <typename T> class GCArraySegment;
class HandleBlock;
+class JSCell;
class VM;
-class MarkStackSegment;
class MarkedBlock;
class WeakBlock;
template <typename T> void deallocate(T*);
template <typename T> void deallocateCustomSize(T*);
+ JS_EXPORT_PRIVATE void releaseFreeRegions();
+
private:
- void waitForRelativeTimeWhileHoldingLock(double relative);
- void waitForRelativeTime(double relative);
+ void waitForDuration(std::chrono::milliseconds);
+ friend ThreadIdentifier createBlockFreeingThread(BlockAllocator*);
void blockFreeingThreadMain();
static void blockFreeingThreadStartFunc(void* heap);
DeadBlock* tryAllocateFromRegion(RegionSet&, DoublyLinkedList<Region>&, size_t&);
bool allRegionSetsAreEmpty() const;
- void releaseFreeRegions();
template <typename T> RegionSet& regionSetFor();
SuperRegion m_superRegion;
RegionSet m_copiedRegionSet;
RegionSet m_markedRegionSet;
- // WeakBlocks and MarkStackSegments use the same RegionSet since they're the same size.
+ // WeakBlocks and GCArraySegments use the same RegionSet since they're the same size.
RegionSet m_fourKBBlockRegionSet;
RegionSet m_workListRegionSet;
bool m_isCurrentlyAllocating;
bool m_blockFreeingThreadShouldQuit;
SpinLock m_regionLock;
- Mutex m_emptyRegionConditionLock;
- ThreadCondition m_emptyRegionCondition;
+ std::mutex m_emptyRegionConditionMutex;
+ std::condition_variable m_emptyRegionCondition;
ThreadIdentifier m_blockFreeingThread;
};
}
if (shouldWakeBlockFreeingThread) {
- MutexLocker mutexLocker(m_emptyRegionConditionLock);
- m_emptyRegionCondition.signal();
+ std::lock_guard<std::mutex> lock(m_emptyRegionConditionMutex);
+ m_emptyRegionCondition.notify_one();
}
-#if PLATFORM(IOS)
- if (!GCActivityCallback::s_shouldCreateGCTimer);
+ if (!m_blockFreeingThread)
releaseFreeRegions();
-#endif
}
template<typename T>
region->destroy();
}
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<CopiedBlock>()
-{
- return m_copiedRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<MarkedBlock>()
-{
- return m_markedRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<WeakBlock>()
-{
- return m_fourKBBlockRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<MarkStackSegment>()
-{
- return m_fourKBBlockRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<CopyWorkListSegment>()
-{
- return m_workListRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HandleBlock>()
-{
- return m_fourKBBlockRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<CopiedBlock> >()
-{
- return m_copiedRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<MarkedBlock> >()
-{
- return m_markedRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<WeakBlock> >()
-{
- return m_fourKBBlockRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<MarkStackSegment> >()
-{
- return m_fourKBBlockRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<CopyWorkListSegment> >()
-{
- return m_workListRegionSet;
-}
-
-template <>
-inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<HandleBlock> >()
-{
- return m_fourKBBlockRegionSet;
-}
+#define REGION_SET_FOR(blockType, set) \
+ template <> \
+ inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<blockType>() \
+ { \
+ return set; \
+ } \
+ template <> \
+ inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<blockType>>() \
+ { \
+ return set; \
+ } \
+
+REGION_SET_FOR(MarkedBlock, m_markedRegionSet);
+REGION_SET_FOR(CopiedBlock, m_copiedRegionSet);
+REGION_SET_FOR(WeakBlock, m_fourKBBlockRegionSet);
+REGION_SET_FOR(GCArraySegment<const JSCell*>, m_fourKBBlockRegionSet);
+REGION_SET_FOR(GCArraySegment<CodeBlock*>, m_fourKBBlockRegionSet);
+REGION_SET_FOR(CopyWorkListSegment, m_workListRegionSet);
+REGION_SET_FOR(HandleBlock, m_fourKBBlockRegionSet);
+
+#undef REGION_SET_FOR
template <typename T>
inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor()