Chromium Code Reviews| 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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 explicit RunDebuggerQueueTask(WorkerThread* thread) : m_thread(thread) { } | 260 explicit RunDebuggerQueueTask(WorkerThread* thread) : m_thread(thread) { } |
| 261 | 261 |
| 262 WorkerThread* m_thread; | 262 WorkerThread* m_thread; |
| 263 }; | 263 }; |
| 264 | 264 |
| 265 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> star tupData) | 265 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> star tupData) |
| 266 : m_started(false) | 266 : m_started(false) |
| 267 , m_terminated(false) | 267 , m_terminated(false) |
| 268 , m_workerLoaderProxy(workerLoaderProxy) | 268 , m_workerLoaderProxy(workerLoaderProxy) |
| 269 , m_workerReportingProxy(workerReportingProxy) | 269 , m_workerReportingProxy(workerReportingProxy) |
| 270 , m_webScheduler(nullptr) | |
| 270 , m_startupData(startupData) | 271 , m_startupData(startupData) |
| 271 , m_isolate(nullptr) | 272 , m_isolate(nullptr) |
| 272 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) | 273 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) |
| 273 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) | 274 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) |
| 274 { | 275 { |
| 275 MutexLocker lock(threadSetMutex()); | 276 MutexLocker lock(threadSetMutex()); |
| 276 workerThreads().add(this); | 277 workerThreads().add(this); |
| 277 } | 278 } |
| 278 | 279 |
| 279 WorkerThread::~WorkerThread() | 280 WorkerThread::~WorkerThread() |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 299 m_workerInspectorController->interruptAndDispatchInspectorCommands(); | 300 m_workerInspectorController->interruptAndDispatchInspectorCommands(); |
| 300 } | 301 } |
| 301 | 302 |
| 302 PlatformThreadId WorkerThread::platformThreadId() | 303 PlatformThreadId WorkerThread::platformThreadId() |
| 303 { | 304 { |
| 304 if (!m_started) | 305 if (!m_started) |
| 305 return 0; | 306 return 0; |
| 306 return backingThread().platformThread().threadId(); | 307 return backingThread().platformThread().threadId(); |
| 307 } | 308 } |
| 308 | 309 |
| 310 // TODO(alexclarke): Use base::Bind instead of this class when the repo's merge. Unfortunately we | |
| 311 // can't use WTF::bind because the type-erasure for member function pointers wit h parameters is broken. | |
|
kinuko
2015/05/13 06:10:52
Could you give a bit more details about what's bro
Sami
2015/05/13 17:54:19
This part was written by Alex so I needed to rever
kinuko
2015/05/14 06:07:05
Ah interesting. Thanks for the detail!
| |
| 312 class WorkerThreadIdleTask : public WebThread::IdleTask { | |
| 313 public: | |
| 314 explicit WorkerThreadIdleTask(WorkerThread* thread) | |
| 315 : m_thread(thread) { } | |
| 316 | |
| 317 ~WorkerThreadIdleTask() override { } | |
| 318 | |
| 319 void run(double deadlineSeconds) override | |
| 320 { | |
| 321 m_thread->performIdleWork(deadlineSeconds); | |
| 322 } | |
| 323 | |
| 324 private: | |
| 325 RawPtr<WorkerThread> m_thread; // NOT OWNED | |
| 326 }; | |
| 327 | |
| 309 void WorkerThread::initialize() | 328 void WorkerThread::initialize() |
| 310 { | 329 { |
| 311 KURL scriptURL = m_startupData->m_scriptURL; | 330 KURL scriptURL = m_startupData->m_scriptURL; |
| 312 String sourceCode = m_startupData->m_sourceCode; | 331 String sourceCode = m_startupData->m_sourceCode; |
| 313 WorkerThreadStartMode startMode = m_startupData->m_startMode; | 332 WorkerThreadStartMode startMode = m_startupData->m_startMode; |
| 314 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e(); | 333 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e(); |
| 315 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; | 334 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; |
| 316 | 335 |
| 336 m_webScheduler = backingThread().platformThread().scheduler(); | |
| 317 { | 337 { |
| 318 MutexLocker lock(m_threadStateMutex); | 338 MutexLocker lock(m_threadStateMutex); |
| 319 | 339 |
| 320 // The worker was terminated before the thread had a chance to run. | 340 // The worker was terminated before the thread had a chance to run. |
| 321 if (m_terminated) { | 341 if (m_terminated) { |
| 322 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 342 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 323 // This can free this thread object, hence it must not be touched af terwards. | 343 // This can free this thread object, hence it must not be touched af terwards. |
| 324 m_workerReportingProxy.workerThreadTerminated(); | 344 m_workerReportingProxy.workerThreadTerminated(); |
| 325 return; | 345 return; |
| 326 } | 346 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 348 if (startMode == PauseWorkerGlobalScopeOnStart) | 368 if (startMode == PauseWorkerGlobalScopeOnStart) |
| 349 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); | 369 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); |
| 350 | 370 |
| 351 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get())); | 371 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get())); |
| 352 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions); | 372 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions); |
| 353 m_workerGlobalScope->didEvaluateWorkerScript(); | 373 m_workerGlobalScope->didEvaluateWorkerScript(); |
| 354 m_workerReportingProxy.didEvaluateWorkerScript(success); | 374 m_workerReportingProxy.didEvaluateWorkerScript(success); |
| 355 | 375 |
| 356 postInitialize(); | 376 postInitialize(); |
| 357 | 377 |
| 358 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs); | 378 m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadIdleTask( this)); |
| 359 } | 379 } |
| 360 | 380 |
| 361 void WorkerThread::shutdown() | 381 void WorkerThread::shutdown() |
| 362 { | 382 { |
| 363 MutexLocker lock(m_threadStateMutex); | 383 MutexLocker lock(m_threadStateMutex); |
| 364 ASSERT(isCurrentThread()); | 384 ASSERT(isCurrentThread()); |
| 365 | 385 |
| 366 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); | 386 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); |
| 367 workerGlobalScope()->dispose(); | 387 workerGlobalScope()->dispose(); |
| 368 willDestroyIsolate(); | 388 willDestroyIsolate(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 | 487 |
| 468 for (WorkerThread* thread : threads) | 488 for (WorkerThread* thread : threads) |
| 469 thread->terminationEvent()->wait(); | 489 thread->terminationEvent()->wait(); |
| 470 } | 490 } |
| 471 | 491 |
| 472 bool WorkerThread::isCurrentThread() | 492 bool WorkerThread::isCurrentThread() |
| 473 { | 493 { |
| 474 return m_started && backingThread().isCurrentThread(); | 494 return m_started && backingThread().isCurrentThread(); |
| 475 } | 495 } |
| 476 | 496 |
| 477 void WorkerThread::idleHandler() | 497 void WorkerThread::performIdleWork(double deadlineSeconds) |
| 478 { | 498 { |
| 479 ASSERT(m_workerGlobalScope.get()); | 499 double gcDeadlineSeconds = deadlineSeconds; |
| 480 int64_t delay = kLongIdleHandlerDelayMs; | |
| 481 | 500 |
| 482 // Do a script engine idle notification if the next event is distant enough. | 501 // The V8 GC does some GC steps (e.g. compaction) only when the idle notific ation is ~1s. |
| 483 const double kMinIdleTimespan = 0.3; | 502 // TODO(rmcilroy): Refactor so extending the deadline like this this isn't n eeded. |
| 484 const double nextFireTime = PlatformThreadData::current().threadTimers().nex tFireTime(); | 503 if (m_webScheduler->canExceedIdleDeadlineIfRequired()) |
| 485 if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan) { | 504 gcDeadlineSeconds = Platform::current()->monotonicallyIncreasingTime() + kLongIdlePeriodSecs; |
| 486 bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::curren t()->monotonicallyIncreasingTime() + 1.0); | |
| 487 if (hasMoreWork) | |
| 488 delay = kShortIdleHandlerDelayMs; | |
| 489 } | |
| 490 | 505 |
| 491 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), delay); | 506 if (doIdleGc(gcDeadlineSeconds)) |
| 507 m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadIdleT ask(this)); | |
| 508 else | |
| 509 m_webScheduler->postIdleTask(FROM_HERE, new WorkerThreadIdleTask(this)); | |
| 510 } | |
| 511 | |
| 512 bool WorkerThread::doIdleGc(double deadlineSeconds) | |
| 513 { | |
| 514 bool gcFinished = false; | |
| 515 if (deadlineSeconds > Platform::current()->monotonicallyIncreasingTime()) | |
| 516 gcFinished = isolate()->IdleNotificationDeadline(deadlineSeconds); | |
| 517 return gcFinished; | |
| 492 } | 518 } |
| 493 | 519 |
| 494 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) | 520 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) |
| 495 { | 521 { |
| 496 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru e).leakPtr()); | 522 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru e).leakPtr()); |
| 497 } | 523 } |
| 498 | 524 |
| 499 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) | 525 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) |
| 500 { | 526 { |
| 501 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta sk, true).leakPtr(), delayMs); | 527 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta sk, true).leakPtr(), delayMs); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 601 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
| 576 } | 602 } |
| 577 | 603 |
| 578 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) | 604 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) |
| 579 { | 605 { |
| 580 MutexLocker locker(m_workerInspectorControllerMutex); | 606 MutexLocker locker(m_workerInspectorControllerMutex); |
| 581 m_workerInspectorController = workerInspectorController; | 607 m_workerInspectorController = workerInspectorController; |
| 582 } | 608 } |
| 583 | 609 |
| 584 } // namespace blink | 610 } // namespace blink |
| OLD | NEW |