]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/GCActivityCallback.cpp
JavaScriptCore-1218.tar.gz
[apple/javascriptcore.git] / runtime / GCActivityCallback.cpp
CommitLineData
14957cd0
A
1/*
2 * Copyright (C) 2010 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 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "config.h"
30#include "GCActivityCallback.h"
31
93a37866
A
32#include "APIShims.h"
33#include "Heap.h"
34#include "VM.h"
35#include "JSLock.h"
36#include "JSObject.h"
37
38#include <wtf/RetainPtr.h>
39#include <wtf/WTFThreadData.h>
40
41#if PLATFORM(EFL)
42#include <wtf/MainThread.h>
43#endif
44
14957cd0
A
45namespace JSC {
46
93a37866 47#if USE(CF) || PLATFORM(QT) || PLATFORM(EFL)
14957cd0 48
93a37866
A
49#if PLATFORM(IOS)
50 bool GCActivityCallback::s_shouldCreateGCTimer = true;
51#endif // PLATFORM(IOS)
52
53const double gcTimeSlicePerMB = 0.01; // Percentage of CPU time we will spend to reclaim 1 MB
54const double maxGCTimeSlice = 0.05; // The maximum amount of CPU time we want to use for opportunistic timer-triggered collections.
55const double timerSlop = 2.0; // Fudge factor to avoid performance cost of resetting timer.
56const double pagingTimeOut = 0.1; // Time in seconds to allow opportunistic timer to iterate over all blocks to see if the Heap is paged out.
57const double hour = 60 * 60;
58
59#if USE(CF)
60DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
61 : GCActivityCallback(heap->vm(), CFRunLoopGetCurrent())
62 , m_delay(s_decade)
14957cd0
A
63{
64}
65
93a37866
A
66DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap, CFRunLoopRef runLoop)
67 : GCActivityCallback(heap->vm(), runLoop)
68 , m_delay(s_decade)
69{
70}
71#elif PLATFORM(QT)
72DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
73 : GCActivityCallback(heap->vm())
74 , m_delay(hour)
75{
76}
77#elif PLATFORM(EFL)
78DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
79 : GCActivityCallback(heap->vm(), WTF::isMainThread())
80 , m_delay(hour)
14957cd0
A
81{
82}
93a37866 83#endif
14957cd0 84
93a37866
A
85void DefaultGCActivityCallback::doWork()
86{
87 Heap* heap = &m_vm->heap;
88 if (!isEnabled())
89 return;
90
91 APIEntryShim shim(m_vm);
92#if !PLATFORM(IOS)
93 double startTime = WTF::monotonicallyIncreasingTime();
94 if (heap->isPagedOut(startTime + pagingTimeOut)) {
95 heap->activityCallback()->cancel();
96 heap->increaseLastGCLength(pagingTimeOut);
97 return;
98 }
99#endif
100 heap->collect(Heap::DoNotSweep);
101}
102
103#if USE(CF)
104void DefaultGCActivityCallback::scheduleTimer(double newDelay)
6fe7ccc8 105{
93a37866
A
106 if (newDelay * timerSlop > m_delay)
107 return;
108 double delta = m_delay - newDelay;
109 m_delay = newDelay;
110 CFRunLoopTimerSetNextFireDate(m_timer.get(), CFRunLoopTimerGetNextFireDate(m_timer.get()) - delta);
6fe7ccc8
A
111}
112
93a37866
A
113void DefaultGCActivityCallback::cancelTimer()
114{
115 m_delay = s_decade;
116 CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + s_decade);
117}
118#elif PLATFORM(QT)
119
120void DefaultGCActivityCallback::scheduleTimer(double newDelay)
14957cd0 121{
93a37866
A
122 if (newDelay * timerSlop > m_delay)
123 return;
124 m_delay = newDelay;
125 m_timer.start(newDelay * 1000, this);
14957cd0
A
126}
127
93a37866 128void DefaultGCActivityCallback::cancelTimer()
14957cd0 129{
93a37866
A
130 m_delay = hour;
131 m_timer.stop();
132}
133#elif PLATFORM(EFL)
134void DefaultGCActivityCallback::scheduleTimer(double newDelay)
135{
136 if (newDelay * timerSlop > m_delay)
137 return;
138
139 stop();
140 m_delay = newDelay;
141
142 ASSERT(!m_timer);
143 m_timer = add(newDelay, this);
144}
145
146void DefaultGCActivityCallback::cancelTimer()
147{
148 m_delay = hour;
149 stop();
150}
151#endif
152
153void DefaultGCActivityCallback::didAllocate(size_t bytes)
154{
155#if PLATFORM(EFL)
156 if (!isEnabled())
157 return;
158
159 ASSERT(WTF::isMainThread());
160#endif
161
162 // The first byte allocated in an allocation cycle will report 0 bytes to didAllocate.
163 // We pretend it's one byte so that we don't ignore this allocation entirely.
164 if (!bytes)
165 bytes = 1;
166 Heap* heap = static_cast<Heap*>(&m_vm->heap);
167 double gcTimeSlice = std::min((static_cast<double>(bytes) / MB) * gcTimeSlicePerMB, maxGCTimeSlice);
168 double newDelay = heap->lastGCLength() / gcTimeSlice;
169 scheduleTimer(newDelay);
170}
171
172void DefaultGCActivityCallback::willCollect()
173{
174 cancelTimer();
14957cd0
A
175}
176
6fe7ccc8 177void DefaultGCActivityCallback::cancel()
93a37866
A
178{
179 cancelTimer();
180}
181
182#else
183
184DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
185 : GCActivityCallback(heap->vm())
186{
187}
188
189void DefaultGCActivityCallback::doWork()
6fe7ccc8
A
190{
191}
192
93a37866 193void DefaultGCActivityCallback::didAllocate(size_t)
6fe7ccc8
A
194{
195}
196
93a37866 197void DefaultGCActivityCallback::willCollect()
6fe7ccc8
A
198{
199}
200
93a37866
A
201void DefaultGCActivityCallback::cancel()
202{
203}
204
205#endif
206
14957cd0
A
207}
208