Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(490)

Side by Side Diff: Source/core/workers/WorkerThread.cpp

Issue 1128093003: Revert of Schedule garbage collection on worker threads using idle tasks (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/workers/WorkerThread.h ('k') | Source/core/workers/WorkerThreadTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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"
50 #include "public/platform/WebThread.h" 49 #include "public/platform/WebThread.h"
51 #include "public/platform/WebWaitableEvent.h" 50 #include "public/platform/WebWaitableEvent.h"
52 #include "wtf/Noncopyable.h" 51 #include "wtf/Noncopyable.h"
53 #include "wtf/WeakPtr.h" 52 #include "wtf/WeakPtr.h"
54 #include "wtf/text/WTFString.h" 53 #include "wtf/text/WTFString.h"
55 54
56 namespace blink { 55 namespace blink {
57 56
58 namespace { 57 namespace {
59 const double kLongIdlePeriodSecs = 1.0; 58 const int64_t kShortIdleHandlerDelayMs = 1000;
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
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)
271 , m_startupData(startupData) 270 , m_startupData(startupData)
272 , m_isolate(nullptr) 271 , m_isolate(nullptr)
273 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) 272 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent()))
274 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) 273 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent()))
275 { 274 {
276 MutexLocker lock(threadSetMutex()); 275 MutexLocker lock(threadSetMutex());
277 workerThreads().add(this); 276 workerThreads().add(this);
278 } 277 }
279 278
280 WorkerThread::~WorkerThread() 279 WorkerThread::~WorkerThread()
(...skipping 19 matching lines...) Expand all
300 m_workerInspectorController->interruptAndDispatchInspectorCommands(); 299 m_workerInspectorController->interruptAndDispatchInspectorCommands();
301 } 300 }
302 301
303 PlatformThreadId WorkerThread::platformThreadId() 302 PlatformThreadId WorkerThread::platformThreadId()
304 { 303 {
305 if (!m_started) 304 if (!m_started)
306 return 0; 305 return 0;
307 return backingThread().platformThread().threadId(); 306 return backingThread().platformThread().threadId();
308 } 307 }
309 308
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.
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
328 void WorkerThread::initialize() 309 void WorkerThread::initialize()
329 { 310 {
330 KURL scriptURL = m_startupData->m_scriptURL; 311 KURL scriptURL = m_startupData->m_scriptURL;
331 String sourceCode = m_startupData->m_sourceCode; 312 String sourceCode = m_startupData->m_sourceCode;
332 WorkerThreadStartMode startMode = m_startupData->m_startMode; 313 WorkerThreadStartMode startMode = m_startupData->m_startMode;
333 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e(); 314 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e();
334 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; 315 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions;
335 316
336 m_webScheduler = backingThread().platformThread().scheduler();
337 { 317 {
338 MutexLocker lock(m_threadStateMutex); 318 MutexLocker lock(m_threadStateMutex);
339 319
340 // The worker was terminated before the thread had a chance to run. 320 // The worker was terminated before the thread had a chance to run.
341 if (m_terminated) { 321 if (m_terminated) {
342 // Notify the proxy that the WorkerGlobalScope has been disposed of. 322 // Notify the proxy that the WorkerGlobalScope has been disposed of.
343 // This can free this thread object, hence it must not be touched af terwards. 323 // This can free this thread object, hence it must not be touched af terwards.
344 m_workerReportingProxy.workerThreadTerminated(); 324 m_workerReportingProxy.workerThreadTerminated();
345 return; 325 return;
346 } 326 }
(...skipping 21 matching lines...) Expand all
368 if (startMode == PauseWorkerGlobalScopeOnStart) 348 if (startMode == PauseWorkerGlobalScopeOnStart)
369 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); 349 m_workerGlobalScope->workerInspectorController()->pauseOnStart();
370 350
371 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get())); 351 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get()));
372 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions); 352 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions);
373 m_workerGlobalScope->didEvaluateWorkerScript(); 353 m_workerGlobalScope->didEvaluateWorkerScript();
374 m_workerReportingProxy.didEvaluateWorkerScript(success); 354 m_workerReportingProxy.didEvaluateWorkerScript(success);
375 355
376 postInitialize(); 356 postInitialize();
377 357
378 m_webScheduler->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadIdleTask( this)); 358 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs);
379 } 359 }
380 360
381 void WorkerThread::shutdown() 361 void WorkerThread::shutdown()
382 { 362 {
383 MutexLocker lock(m_threadStateMutex); 363 MutexLocker lock(m_threadStateMutex);
384 ASSERT(isCurrentThread()); 364 ASSERT(isCurrentThread());
385 365
386 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); 366 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr);
387 workerGlobalScope()->dispose(); 367 workerGlobalScope()->dispose();
388 willDestroyIsolate(); 368 willDestroyIsolate();
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 467
488 for (WorkerThread* thread : threads) 468 for (WorkerThread* thread : threads)
489 thread->terminationEvent()->wait(); 469 thread->terminationEvent()->wait();
490 } 470 }
491 471
492 bool WorkerThread::isCurrentThread() 472 bool WorkerThread::isCurrentThread()
493 { 473 {
494 return m_started && backingThread().isCurrentThread(); 474 return m_started && backingThread().isCurrentThread();
495 } 475 }
496 476
497 void WorkerThread::performIdleWork(double deadlineSeconds) 477 void WorkerThread::idleHandler()
498 { 478 {
499 double gcDeadlineSeconds = deadlineSeconds; 479 ASSERT(m_workerGlobalScope.get());
480 int64_t delay = kLongIdleHandlerDelayMs;
500 481
501 // The V8 GC does some GC steps (e.g. compaction) only when the idle notific ation is ~1s. 482 // Do a script engine idle notification if the next event is distant enough.
502 // TODO(rmcilroy): Refactor so extending the deadline like this this isn't n eeded. 483 const double kMinIdleTimespan = 0.3;
503 if (m_webScheduler->canExceedIdleDeadlineIfRequired()) 484 const double nextFireTime = PlatformThreadData::current().threadTimers().nex tFireTime();
504 gcDeadlineSeconds = Platform::current()->monotonicallyIncreasingTime() + kLongIdlePeriodSecs; 485 if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan) {
486 bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::curren t()->monotonicallyIncreasingTime() + 1.0);
487 if (hasMoreWork)
488 delay = kShortIdleHandlerDelayMs;
489 }
505 490
506 if (doIdleGc(gcDeadlineSeconds)) 491 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), delay);
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;
518 } 492 }
519 493
520 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) 494 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task)
521 { 495 {
522 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru e).leakPtr()); 496 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru e).leakPtr());
523 } 497 }
524 498
525 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) 499 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs)
526 { 500 {
527 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta sk, true).leakPtr(), delayMs); 501 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta sk, true).leakPtr(), delayMs);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); 575 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get());
602 } 576 }
603 577
604 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) 578 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController)
605 { 579 {
606 MutexLocker locker(m_workerInspectorControllerMutex); 580 MutexLocker locker(m_workerInspectorControllerMutex);
607 m_workerInspectorController = workerInspectorController; 581 m_workerInspectorController = workerInspectorController;
608 } 582 }
609 583
610 } // namespace blink 584 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/workers/WorkerThread.h ('k') | Source/core/workers/WorkerThreadTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698