Index: Source/core/workers/WorkerThread.cpp |
diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp |
index 2d4f884a4dd7faf10819784ab2d08c195fa878ab..668e8d1d3968cb7df1ec2e977b4f0b020ea2ce9a 100644 |
--- a/Source/core/workers/WorkerThread.cpp |
+++ b/Source/core/workers/WorkerThread.cpp |
@@ -164,6 +164,12 @@ public: |
m_task->performTask(workerGlobalScope); |
if (m_isInstrumented) |
InspectorInstrumentation::didPerformExecutionContextTask(workerGlobalScope); |
+ |
+ // If no more tasks are queued up after this, then queue up the idleHandler |
+ // to trigger GC. |
+ WorkerThread& workerThread = const_cast<WorkerThread&>(m_workerThread); |
+ if (!workerThread.decrementAndReturnTaskCount() && !workerThread.isIdleHandlerTaskFiredOnce()) |
jochen (gone - plz use gerrit)
2014/09/02 10:14:14
maybe teach WorkerThreadTask that it's an idle tas
Mayur Kankanwadi
2014/09/03 11:26:21
Done.
|
+ workerThread.queueUpIdleHandlerNow(); |
} |
private: |
@@ -207,6 +213,9 @@ WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReporting |
, m_workerReportingProxy(workerReportingProxy) |
, m_startupData(startupData) |
, m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent())) |
+ , m_tasksCount(0) |
+ , m_isIdleHandlerTaskFiredOnce(false) |
+ , m_isIdleHandlerTask(false) |
{ |
MutexLocker lock(threadSetMutex()); |
workerThreads().add(this); |
@@ -402,6 +411,19 @@ bool WorkerThread::isCurrentThread() const |
return m_thread && m_thread->isCurrentThread(); |
} |
+bool WorkerThread::isIdleHandlerTaskFiredOnce() |
+{ |
+ MutexLocker lock(m_taskCounterMutex); |
+ return m_isIdleHandlerTaskFiredOnce; |
+} |
+ |
+void WorkerThread::queueUpIdleHandlerNow() |
+{ |
+ m_isIdleHandlerTask = m_isIdleHandlerTaskFiredOnce = true; |
+ postTask(createSameThreadTask(&WorkerThread::idleHandler, this)); |
+ m_isIdleHandlerTask = false; |
jochen (gone - plz use gerrit)
2014/09/02 10:14:14
instead of using m_isIdleHandlerTask, this method
Mayur Kankanwadi
2014/09/03 11:26:21
Done.
|
+} |
+ |
void WorkerThread::idleHandler() |
{ |
ASSERT(m_workerGlobalScope.get()); |
@@ -409,22 +431,60 @@ void WorkerThread::idleHandler() |
// Do a script engine idle notification if the next event is distant enough. |
const double kMinIdleTimespan = 0.3; |
+ // This is set to true when idleNotification returns false. |
+ // idleNotification returns false only when more GC is required. It returns |
+ // true if no more GC is required and that is when callGCAgain will be set to false. |
+ bool callGCAgain = false; |
if (m_sharedTimer->nextFireTime() == 0.0 || m_sharedTimer->nextFireTime() > currentTime() + kMinIdleTimespan) { |
- bool hasMoreWork = !m_workerGlobalScope->idleNotification(); |
- if (hasMoreWork) |
+ bool callGCAgain = !m_workerGlobalScope->idleNotification(); |
Mayur Kankanwadi
2014/09/03 11:26:21
This(bool callGCAgain) was an extra definition, wi
|
+ if (callGCAgain) |
delay = kShortIdleHandlerDelayMs; |
} |
+ if (callGCAgain) { |
+ postDelayedTask(createSameThreadTask(&WorkerThread::idleHandler, this), delay); |
+ } |
+} |
- postDelayedTask(createSameThreadTask(&WorkerThread::idleHandler, this), delay); |
+void WorkerThread::decrementTaskCount() |
jochen (gone - plz use gerrit)
2014/09/02 10:14:14
this method isn't used anywhere?
Mayur Kankanwadi
2014/09/03 11:26:22
True.Removed it.
|
+{ |
+ MutexLocker lock(m_taskCounterMutex); |
+ if (!m_tasksCount) |
+ return; |
+ --m_tasksCount; |
+} |
+ |
+unsigned WorkerThread::decrementAndReturnTaskCount() |
+{ |
+ MutexLocker lock(m_taskCounterMutex); |
+ if (!m_tasksCount) |
jochen (gone - plz use gerrit)
2014/09/02 10:14:14
see my comment about not invoking this for idle ta
Mayur Kankanwadi
2014/09/03 11:26:21
Done.
|
+ return 0; |
+ --m_tasksCount; |
+ return m_tasksCount; |
+} |
+ |
+unsigned WorkerThread::taskCount() |
jochen (gone - plz use gerrit)
2014/09/02 10:14:14
not used anywhere?
Mayur Kankanwadi
2014/09/03 11:26:22
True.Removed it.
|
+{ |
+ MutexLocker lock(m_taskCounterMutex); |
+ return m_tasksCount; |
} |
void WorkerThread::postTask(PassOwnPtr<ExecutionContextTask> task) |
{ |
+ if (!m_isIdleHandlerTask) { |
+ MutexLocker lock(m_taskCounterMutex); |
+ ++m_tasksCount; |
+ m_isIdleHandlerTaskFiredOnce = false; |
+ } |
m_thread->postTask(WorkerThreadTask::create(*this, task, true).leakPtr()); |
} |
void WorkerThread::postDelayedTask(PassOwnPtr<ExecutionContextTask> task, long long delayMs) |
{ |
+ if (!m_isIdleHandlerTask) { |
+ MutexLocker lock(m_taskCounterMutex); |
+ ++m_tasksCount; |
+ m_isIdleHandlerTaskFiredOnce = false; |
+ } |
m_thread->postDelayedTask(WorkerThreadTask::create(*this, task, true).leakPtr(), delayMs); |
} |