Index: Source/core/workers/WorkerThread.cpp |
diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp |
index 55202cc58b653b6ea4b768c2e212a8088183daec..cf9f4b4609a5279c4ac7d10d7e3848b8a02c7657 100644 |
--- a/Source/core/workers/WorkerThread.cpp |
+++ b/Source/core/workers/WorkerThread.cpp |
@@ -46,6 +46,7 @@ |
#include "platform/heap/ThreadState.h" |
#include "platform/weborigin/KURL.h" |
#include "public/platform/Platform.h" |
+#include "public/platform/WebScheduler.h" |
#include "public/platform/WebThread.h" |
#include "public/platform/WebWaitableEvent.h" |
#include "wtf/Noncopyable.h" |
@@ -55,8 +56,7 @@ |
namespace blink { |
namespace { |
-const int64_t kShortIdleHandlerDelayMs = 1000; |
-const int64_t kLongIdleHandlerDelayMs = 10*1000; |
+const double kLongIdlePeriodSecs = 1.0; |
} // namespace |
@@ -267,6 +267,7 @@ WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work |
, m_terminated(false) |
, m_workerLoaderProxy(workerLoaderProxy) |
, m_workerReportingProxy(workerReportingProxy) |
+ , m_webScheduler(nullptr) |
, m_startupData(startupData) |
, m_isolate(nullptr) |
, m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) |
@@ -306,6 +307,24 @@ PlatformThreadId WorkerThread::platformThreadId() |
return backingThread().platformThread().threadId(); |
} |
+// TODO(alexclarke): Use base::Bind instead of this class when the repo's merge. Unfortunately we |
+// can't use WTF::bind because the type-erasure for member function pointers with parameters is broken. |
+class WorkerThreadIdleTask : public WebThread::IdleTask { |
+public: |
+ explicit WorkerThreadIdleTask(WorkerThread* thread) |
+ : m_thread(thread) { } |
+ |
+ ~WorkerThreadIdleTask() override { } |
+ |
+ void run(double deadlineSeconds) override |
+ { |
+ m_thread->performIdleWork(deadlineSeconds); |
+ } |
+ |
+private: |
+ RawPtr<WorkerThread> m_thread; // NOT OWNED |
+}; |
+ |
void WorkerThread::initialize() |
{ |
KURL scriptURL = m_startupData->m_scriptURL; |
@@ -314,6 +333,7 @@ void WorkerThread::initialize() |
OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.release(); |
V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; |
+ m_webScheduler = backingThread().platformThread().scheduler(); |
{ |
MutexLocker lock(m_threadCreationMutex); |
@@ -355,7 +375,7 @@ void WorkerThread::initialize() |
postInitialize(); |
- postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs); |
+ m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadIdleTask(this)); |
alex clarke (OOO till 29th)
2015/05/12 08:42:14
I wonder how this is going to interact with the qu
Sami
2015/05/12 10:05:32
I think this should Just Work(tm), because the sha
|
} |
void WorkerThread::cleanup() |
@@ -474,21 +494,27 @@ bool WorkerThread::isCurrentThread() |
return m_started && backingThread().isCurrentThread(); |
} |
-void WorkerThread::idleHandler() |
+void WorkerThread::performIdleWork(double deadlineSeconds) |
{ |
- ASSERT(m_workerGlobalScope.get()); |
- int64_t delay = kLongIdleHandlerDelayMs; |
+ double gcDeadlineSeconds = deadlineSeconds; |
- // Do a script engine idle notification if the next event is distant enough. |
- const double kMinIdleTimespan = 0.3; |
- const double nextFireTime = PlatformThreadData::current().threadTimers().nextFireTime(); |
- if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan) { |
- bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::current()->monotonicallyIncreasingTime() + 1.0); |
- if (hasMoreWork) |
- delay = kShortIdleHandlerDelayMs; |
+ // The V8 GC does some GC steps (e.g. compaction) only when the idle notification is ~1s. |
+ // TODO(rmcilroy): Refactor so extending the deadline like this this isn't needed. |
+ if (m_webScheduler->canExceedIdleDeadlineIfRequired()) |
+ gcDeadlineSeconds = Platform::current()->monotonicallyIncreasingTime() + kLongIdlePeriodSecs; |
+ |
+ if (doIdleGc(gcDeadlineSeconds)) |
+ m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadIdleTask(this)); |
+ else |
+ m_webScheduler->postIdleTask(FROM_HERE, new WorkerThreadIdleTask(this)); |
} |
- postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), delay); |
+bool WorkerThread::doIdleGc(double deadlineSeconds) |
+{ |
+ bool gcFinished = false; |
+ if (deadlineSeconds > Platform::current()->monotonicallyIncreasingTime()) |
+ gcFinished = isolate()->IdleNotificationDeadline(deadlineSeconds); |
+ return gcFinished; |
} |
void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<ExecutionContextTask> task) |