#include "config.h" #include "IncrementalSweeper.h" #include "APIShims.h" #include "Heap.h" #include "JSObject.h" #include "JSString.h" #include "MarkedBlock.h" #include "ScopeChain.h" #include #include namespace JSC { #if USE(CF) static const CFTimeInterval decade = 60 * 60 * 24 * 365 * 10; static const CFTimeInterval sweepTimeSlicePerBlock = 0.01; static const CFTimeInterval sweepTimeMultiplier = 1.0 / sweepTimeSlicePerBlock; void IncrementalSweeper::timerDidFire(CFRunLoopTimerRef, void* info) { Heap* heap = static_cast(info); APIEntryShim shim(heap->globalData()); heap->sweeper()->doSweep(WTF::monotonicallyIncreasingTime()); } IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop) : m_heap(heap) , m_currentBlockToSweepIndex(0) , m_lengthOfLastSweepIncrement(0.0) { memset(&m_context, 0, sizeof(CFRunLoopTimerContext)); m_context.info = m_heap; m_runLoop = runLoop; m_timer.adoptCF(CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent(), decade, 0, 0, &timerDidFire, &m_context)); CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes); } IncrementalSweeper::~IncrementalSweeper() { CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes); CFRunLoopTimerInvalidate(m_timer.get()); } PassOwnPtr IncrementalSweeper::create(Heap* heap) { return adoptPtr(new IncrementalSweeper(heap, CFRunLoopGetCurrent())); } void IncrementalSweeper::scheduleTimer() { CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + (m_lengthOfLastSweepIncrement * sweepTimeMultiplier)); } void IncrementalSweeper::cancelTimer() { CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + decade); } void IncrementalSweeper::doSweep(double sweepBeginTime) { for (; m_currentBlockToSweepIndex < m_blocksToSweep.size(); m_currentBlockToSweepIndex++) { MarkedBlock* nextBlock = m_blocksToSweep[m_currentBlockToSweepIndex]; if (!nextBlock->needsSweeping()) continue; nextBlock->sweep(); m_blocksToSweep[m_currentBlockToSweepIndex++] = 0; m_lengthOfLastSweepIncrement = WTF::monotonicallyIncreasingTime() - sweepBeginTime; scheduleTimer(); return; } m_blocksToSweep.clear(); cancelTimer(); } void IncrementalSweeper::startSweeping(const HashSet& blockSnapshot) { WTF::copyToVector(blockSnapshot, m_blocksToSweep); m_currentBlockToSweepIndex = 0; scheduleTimer(); } #else IncrementalSweeper::IncrementalSweeper() { } IncrementalSweeper::~IncrementalSweeper() { } PassOwnPtr IncrementalSweeper::create(Heap*) { return adoptPtr(new IncrementalSweeper()); } void IncrementalSweeper::startSweeping(const HashSet&) { } #endif } // namespace JSC