1/* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "IncrementalSweeper.h" 28 29#include "APIShims.h" 30#include "Heap.h" 31#include "JSObject.h" 32#include "JSString.h" 33#include "MarkedBlock.h" 34 35#include <wtf/HashSet.h> 36#include <wtf/WTFThreadData.h> 37 38namespace JSC { 39 40#if USE(CF) || PLATFORM(BLACKBERRY) || PLATFORM(QT) 41 42static const double sweepTimeSlice = .01; // seconds 43static const double sweepTimeTotal = .10; 44static const double sweepTimeMultiplier = 1.0 / sweepTimeTotal; 45 46#if USE(CF) 47 48IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop) 49 : HeapTimer(heap->vm(), runLoop) 50 , m_currentBlockToSweepIndex(0) 51 , m_blocksToSweep(heap->m_blockSnapshot) 52{ 53} 54 55PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap) 56{ 57 return adoptPtr(new IncrementalSweeper(heap, CFRunLoopGetCurrent())); 58} 59 60void IncrementalSweeper::scheduleTimer() 61{ 62 CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + (sweepTimeSlice * sweepTimeMultiplier)); 63} 64 65void IncrementalSweeper::cancelTimer() 66{ 67 CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + s_decade); 68} 69 70#elif PLATFORM(BLACKBERRY) || PLATFORM(QT) 71 72IncrementalSweeper::IncrementalSweeper(Heap* heap) 73 : HeapTimer(heap->vm()) 74 , m_currentBlockToSweepIndex(0) 75 , m_blocksToSweep(heap->m_blockSnapshot) 76{ 77} 78 79PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap) 80{ 81 return adoptPtr(new IncrementalSweeper(heap)); 82} 83 84void IncrementalSweeper::scheduleTimer() 85{ 86#if PLATFORM(QT) 87 m_timer.start(sweepTimeSlice * sweepTimeMultiplier * 1000, this); 88#else 89 m_timer.start(sweepTimeSlice * sweepTimeMultiplier); 90#endif 91} 92 93void IncrementalSweeper::cancelTimer() 94{ 95 m_timer.stop(); 96} 97 98#endif 99 100void IncrementalSweeper::doWork() 101{ 102 doSweep(WTF::monotonicallyIncreasingTime()); 103} 104 105void IncrementalSweeper::doSweep(double sweepBeginTime) 106{ 107 while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { 108 sweepNextBlock(); 109 110 double elapsedTime = WTF::monotonicallyIncreasingTime() - sweepBeginTime; 111 if (elapsedTime < sweepTimeSlice) 112 continue; 113 114 scheduleTimer(); 115 return; 116 } 117 118 m_blocksToSweep.clear(); 119 cancelTimer(); 120} 121 122void IncrementalSweeper::sweepNextBlock() 123{ 124 while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { 125 MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++]; 126 127 if (!block->needsSweeping()) 128 continue; 129 130 block->sweep(); 131 m_vm->heap.objectSpace().freeOrShrinkBlock(block); 132 return; 133 } 134} 135 136void IncrementalSweeper::startSweeping(Vector<MarkedBlock*>& blockSnapshot) 137{ 138 m_blocksToSweep = blockSnapshot; 139 m_currentBlockToSweepIndex = 0; 140 scheduleTimer(); 141} 142 143void IncrementalSweeper::willFinishSweeping() 144{ 145 m_currentBlockToSweepIndex = 0; 146 m_blocksToSweep.clear(); 147 if (m_vm) 148 cancelTimer(); 149} 150 151#else 152 153IncrementalSweeper::IncrementalSweeper(VM* vm) 154 : HeapTimer(vm) 155{ 156} 157 158void IncrementalSweeper::doWork() 159{ 160} 161 162PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap) 163{ 164 return adoptPtr(new IncrementalSweeper(heap->vm())); 165} 166 167void IncrementalSweeper::startSweeping(Vector<MarkedBlock*>&) 168{ 169} 170 171void IncrementalSweeper::willFinishSweeping() 172{ 173} 174 175void IncrementalSweeper::sweepNextBlock() 176{ 177} 178 179#endif 180 181} // namespace JSC 182