| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 #include "core/workers/WorkerReportingProxy.h" | 39 #include "core/workers/WorkerReportingProxy.h" |
| 40 #include "core/workers/WorkerThreadStartupData.h" | 40 #include "core/workers/WorkerThreadStartupData.h" |
| 41 #include "platform/PlatformThreadData.h" | 41 #include "platform/PlatformThreadData.h" |
| 42 #include "platform/Task.h" | 42 #include "platform/Task.h" |
| 43 #include "platform/ThreadSafeFunctional.h" | 43 #include "platform/ThreadSafeFunctional.h" |
| 44 #include "platform/ThreadTimers.h" | 44 #include "platform/ThreadTimers.h" |
| 45 #include "platform/heap/SafePoint.h" | 45 #include "platform/heap/SafePoint.h" |
| 46 #include "platform/heap/ThreadState.h" | 46 #include "platform/heap/ThreadState.h" |
| 47 #include "platform/weborigin/KURL.h" | 47 #include "platform/weborigin/KURL.h" |
| 48 #include "public/platform/Platform.h" | 48 #include "public/platform/Platform.h" |
| 49 #include "public/platform/WebScheduler.h" |
| 49 #include "public/platform/WebThread.h" | 50 #include "public/platform/WebThread.h" |
| 50 #include "public/platform/WebWaitableEvent.h" | 51 #include "public/platform/WebWaitableEvent.h" |
| 51 #include "wtf/Noncopyable.h" | 52 #include "wtf/Noncopyable.h" |
| 52 #include "wtf/WeakPtr.h" | 53 #include "wtf/WeakPtr.h" |
| 53 #include "wtf/text/WTFString.h" | 54 #include "wtf/text/WTFString.h" |
| 54 | 55 |
| 55 namespace blink { | 56 namespace blink { |
| 56 | 57 |
| 57 namespace { | 58 namespace { |
| 58 const int64_t kShortIdleHandlerDelayMs = 1000; | 59 const double kLongIdlePeriodSecs = 1.0; |
| 59 const int64_t kLongIdleHandlerDelayMs = 10*1000; | |
| 60 | 60 |
| 61 } // namespace | 61 } // namespace |
| 62 | 62 |
| 63 class WorkerMicrotaskRunner : public WebThread::TaskObserver { | 63 class WorkerMicrotaskRunner : public WebThread::TaskObserver { |
| 64 public: | 64 public: |
| 65 explicit WorkerMicrotaskRunner(WorkerThread* workerThread) | 65 explicit WorkerMicrotaskRunner(WorkerThread* workerThread) |
| 66 : m_workerThread(workerThread) | 66 : m_workerThread(workerThread) |
| 67 { | 67 { |
| 68 } | 68 } |
| 69 | 69 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 explicit RunDebuggerQueueTask(WorkerThread* thread) : m_thread(thread) { } | 265 explicit RunDebuggerQueueTask(WorkerThread* thread) : m_thread(thread) { } |
| 266 | 266 |
| 267 WorkerThread* m_thread; | 267 WorkerThread* m_thread; |
| 268 }; | 268 }; |
| 269 | 269 |
| 270 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work
erReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> star
tupData) | 270 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work
erReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> star
tupData) |
| 271 : m_started(false) | 271 : m_started(false) |
| 272 , m_terminated(false) | 272 , m_terminated(false) |
| 273 , m_workerLoaderProxy(workerLoaderProxy) | 273 , m_workerLoaderProxy(workerLoaderProxy) |
| 274 , m_workerReportingProxy(workerReportingProxy) | 274 , m_workerReportingProxy(workerReportingProxy) |
| 275 , m_webScheduler(nullptr) |
| 275 , m_startupData(startupData) | 276 , m_startupData(startupData) |
| 276 , m_isolate(nullptr) | 277 , m_isolate(nullptr) |
| 277 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) | 278 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) |
| 278 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) | 279 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) |
| 279 { | 280 { |
| 280 MutexLocker lock(threadSetMutex()); | 281 MutexLocker lock(threadSetMutex()); |
| 281 workerThreads().add(this); | 282 workerThreads().add(this); |
| 282 } | 283 } |
| 283 | 284 |
| 284 WorkerThread::~WorkerThread() | 285 WorkerThread::~WorkerThread() |
| (...skipping 27 matching lines...) Expand all Loading... |
| 312 } | 313 } |
| 313 | 314 |
| 314 void WorkerThread::initialize() | 315 void WorkerThread::initialize() |
| 315 { | 316 { |
| 316 KURL scriptURL = m_startupData->m_scriptURL; | 317 KURL scriptURL = m_startupData->m_scriptURL; |
| 317 String sourceCode = m_startupData->m_sourceCode; | 318 String sourceCode = m_startupData->m_sourceCode; |
| 318 WorkerThreadStartMode startMode = m_startupData->m_startMode; | 319 WorkerThreadStartMode startMode = m_startupData->m_startMode; |
| 319 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas
e(); | 320 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas
e(); |
| 320 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; | 321 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; |
| 321 | 322 |
| 323 m_webScheduler = backingThread().platformThread().scheduler(); |
| 322 { | 324 { |
| 323 MutexLocker lock(m_threadStateMutex); | 325 MutexLocker lock(m_threadStateMutex); |
| 324 | 326 |
| 325 // The worker was terminated before the thread had a chance to run. | 327 // The worker was terminated before the thread had a chance to run. |
| 326 if (m_terminated) { | 328 if (m_terminated) { |
| 327 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 329 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 328 // This can free this thread object, hence it must not be touched af
terwards. | 330 // This can free this thread object, hence it must not be touched af
terwards. |
| 329 m_workerReportingProxy.workerThreadTerminated(); | 331 m_workerReportingProxy.workerThreadTerminated(); |
| 330 return; | 332 return; |
| 331 } | 333 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 353 if (startMode == PauseWorkerGlobalScopeOnStart) | 355 if (startMode == PauseWorkerGlobalScopeOnStart) |
| 354 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); | 356 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); |
| 355 | 357 |
| 356 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip
tCachedMetadataHandler(scriptURL, cachedMetaData.get())); | 358 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip
tCachedMetadataHandler(scriptURL, cachedMetaData.get())); |
| 357 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul
lptr, handler.get(), v8CacheOptions); | 359 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul
lptr, handler.get(), v8CacheOptions); |
| 358 m_workerGlobalScope->didEvaluateWorkerScript(); | 360 m_workerGlobalScope->didEvaluateWorkerScript(); |
| 359 m_workerReportingProxy.didEvaluateWorkerScript(success); | 361 m_workerReportingProxy.didEvaluateWorkerScript(success); |
| 360 | 362 |
| 361 postInitialize(); | 363 postInitialize(); |
| 362 | 364 |
| 363 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler,
this), kShortIdleHandlerDelayMs); | 365 m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, WTF::bind<double>(&Worker
Thread::performIdleWork, this)); |
| 364 } | 366 } |
| 365 | 367 |
| 366 void WorkerThread::shutdown() | 368 void WorkerThread::shutdown() |
| 367 { | 369 { |
| 368 MutexLocker lock(m_threadStateMutex); | 370 MutexLocker lock(m_threadStateMutex); |
| 369 ASSERT(isCurrentThread()); | 371 ASSERT(isCurrentThread()); |
| 370 | 372 |
| 371 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); | 373 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); |
| 372 workerGlobalScope()->dispose(); | 374 workerGlobalScope()->dispose(); |
| 373 willDestroyIsolate(); | 375 willDestroyIsolate(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 | 474 |
| 473 for (WorkerThread* thread : threads) | 475 for (WorkerThread* thread : threads) |
| 474 thread->terminationEvent()->wait(); | 476 thread->terminationEvent()->wait(); |
| 475 } | 477 } |
| 476 | 478 |
| 477 bool WorkerThread::isCurrentThread() | 479 bool WorkerThread::isCurrentThread() |
| 478 { | 480 { |
| 479 return m_started && backingThread().isCurrentThread(); | 481 return m_started && backingThread().isCurrentThread(); |
| 480 } | 482 } |
| 481 | 483 |
| 482 void WorkerThread::idleHandler() | 484 void WorkerThread::performIdleWork(double deadlineSeconds) |
| 483 { | 485 { |
| 484 ASSERT(m_workerGlobalScope.get()); | 486 double gcDeadlineSeconds = deadlineSeconds; |
| 485 int64_t delay = kLongIdleHandlerDelayMs; | |
| 486 | 487 |
| 487 // Do a script engine idle notification if the next event is distant enough. | 488 // The V8 GC does some GC steps (e.g. compaction) only when the idle notific
ation is ~1s. |
| 488 const double kMinIdleTimespan = 0.3; | 489 // TODO(rmcilroy): Refactor so extending the deadline like this this isn't n
eeded. |
| 489 const double nextFireTime = PlatformThreadData::current().threadTimers().nex
tFireTime(); | 490 if (m_webScheduler->canExceedIdleDeadlineIfRequired()) |
| 490 if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan)
{ | 491 gcDeadlineSeconds = Platform::current()->monotonicallyIncreasingTime() +
kLongIdlePeriodSecs; |
| 491 bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::curren
t()->monotonicallyIncreasingTime() + 1.0); | |
| 492 if (hasMoreWork) | |
| 493 delay = kShortIdleHandlerDelayMs; | |
| 494 } | |
| 495 | 492 |
| 496 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler,
this), delay); | 493 if (doIdleGc(gcDeadlineSeconds)) |
| 494 m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, WTF::bind<double>(&Wo
rkerThread::performIdleWork, this)); |
| 495 else |
| 496 m_webScheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&WorkerThread:
:performIdleWork, this)); |
| 497 } |
| 498 |
| 499 bool WorkerThread::doIdleGc(double deadlineSeconds) |
| 500 { |
| 501 bool gcFinished = false; |
| 502 if (deadlineSeconds > Platform::current()->monotonicallyIncreasingTime()) |
| 503 gcFinished = isolate()->IdleNotificationDeadline(deadlineSeconds); |
| 504 return gcFinished; |
| 497 } | 505 } |
| 498 | 506 |
| 499 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi
onContextTask> task) | 507 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi
onContextTask> task) |
| 500 { | 508 { |
| 501 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru
e).leakPtr()); | 509 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru
e).leakPtr()); |
| 502 } | 510 } |
| 503 | 511 |
| 504 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr<
ExecutionContextTask> task, long long delayMs) | 512 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr<
ExecutionContextTask> task, long long delayMs) |
| 505 { | 513 { |
| 506 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta
sk, true).leakPtr(), delayMs); | 514 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta
sk, true).leakPtr(), delayMs); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 588 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
| 581 } | 589 } |
| 582 | 590 |
| 583 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) | 591 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) |
| 584 { | 592 { |
| 585 MutexLocker locker(m_workerInspectorControllerMutex); | 593 MutexLocker locker(m_workerInspectorControllerMutex); |
| 586 m_workerInspectorController = workerInspectorController; | 594 m_workerInspectorController = workerInspectorController; |
| 587 } | 595 } |
| 588 | 596 |
| 589 } // namespace blink | 597 } // namespace blink |
| OLD | NEW |