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

Side by Side Diff: Source/core/html/HTMLMediaElement.cpp

Issue 1184373006: Oilpan: add prefinalizer for HTMLMediaElement. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: move out a potentially-allocating action from prefinalizer Created 5 years, 6 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
« no previous file with comments | « Source/core/html/HTMLMediaElement.h ('k') | no next file » | 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) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 #endif 361 #endif
362 , m_initialPlayWithoutUserGestures(false) 362 , m_initialPlayWithoutUserGestures(false)
363 , m_autoplayMediaCounted(false) 363 , m_autoplayMediaCounted(false)
364 , m_audioTracks(AudioTrackList::create(*this)) 364 , m_audioTracks(AudioTrackList::create(*this))
365 , m_videoTracks(VideoTrackList::create(*this)) 365 , m_videoTracks(VideoTrackList::create(*this))
366 , m_textTracks(nullptr) 366 , m_textTracks(nullptr)
367 #if ENABLE(WEB_AUDIO) 367 #if ENABLE(WEB_AUDIO)
368 , m_audioSourceNode(nullptr) 368 , m_audioSourceNode(nullptr)
369 #endif 369 #endif
370 { 370 {
371 #if ENABLE(OILPAN)
372 ThreadState::current()->registerPreFinalizer(*this);
373 #endif
371 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); 374 ASSERT(RuntimeEnabledFeatures::mediaEnabled());
372 375
373 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); 376 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this);
374 377
375 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) 378 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture())
376 m_userGestureRequiredForPlay = true; 379 m_userGestureRequiredForPlay = true;
377 380
378 setHasCustomStyleCallbacks(); 381 setHasCustomStyleCallbacks();
379 addElementToDocumentMap(this, &document); 382 addElementToDocumentMap(this, &document);
380 } 383 }
381 384
382 HTMLMediaElement::~HTMLMediaElement() 385 HTMLMediaElement::~HTMLMediaElement()
383 { 386 {
384 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); 387 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this);
385 388
386 #if ENABLE(OILPAN) 389 #if ENABLE(OILPAN)
387 // If the HTMLMediaElement dies with the document we are not 390 if (m_closeMediaSourceWhenFinalizing)
haraken 2015/06/17 20:29:02 I guess this hack could be moved to the pre-finali
sof 2015/06/17 20:40:46 I don't think it can be, as it allocates & fires a
haraken 2015/06/17 20:47:15 Allocation is allowed in pre-finalizers. closeMed
388 // allowed to touch the document to adjust delay load event counts 391 closeMediaSource();
389 // because the document could have been already 392
390 // destructed. However, if the HTMLMediaElement dies with the 393 // Oilpan: the player must be released, but the player object
391 // document there is no need to change the delayed load counts 394 // cannot safely access this player client any longer as parts of
392 // because no load event will fire anyway. If the document is 395 // it may have been finalized already (like the media element's
393 // still alive we do have to decrement the load delay counts. We 396 // supplementable table.) Handled for now by entering an
394 // determine if the document is alive via the ActiveDOMObject 397 // is-finalizing state, which is explicitly checked for if the
395 // which is a context lifecycle observer. If the Document has been 398 // player tries to access the media element during shutdown.
396 // destructed ActiveDOMObject::executionContext() returns 0. 399 //
397 if (ActiveDOMObject::executionContext()) 400 // FIXME: Oilpan: move the media player to the heap instead and
398 setShouldDelayLoadEvent(false); 401 // avoid having to finalize it from here; this whole #if block
402 // could then be removed (along with the state bit it depends on.)
403 // crbug.com/378229
404 m_isFinalizing = true;
399 #else 405 #else
400 // HTMLMediaElement and m_asyncEventQueue always become unreachable 406 // HTMLMediaElement and m_asyncEventQueue always become unreachable
401 // together. So HTMLMediaElemenet and m_asyncEventQueue are destructed in 407 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in
402 // the same GC. We don't need to close it explicitly in Oilpan. 408 // the same GC. We don't need to close it explicitly in Oilpan.
403 m_asyncEventQueue->close(); 409 m_asyncEventQueue->close();
404 410
405 setShouldDelayLoadEvent(false); 411 setShouldDelayLoadEvent(false);
406 412
407 if (m_textTracks) 413 if (m_textTracks)
408 m_textTracks->clearOwner(); 414 m_textTracks->clearOwner();
409 m_audioTracks->shutdown(); 415 m_audioTracks->shutdown();
410 m_videoTracks->shutdown(); 416 m_videoTracks->shutdown();
411 417
412 if (m_mediaController) { 418 if (m_mediaController) {
413 m_mediaController->removeMediaElement(this); 419 m_mediaController->removeMediaElement(this);
414 m_mediaController = nullptr; 420 m_mediaController = nullptr;
415 } 421 }
416 #endif
417
418 #if ENABLE(OILPAN)
419 if (m_closeMediaSourceWhenFinalizing)
420 closeMediaSource();
421 #else
422 closeMediaSource(); 422 closeMediaSource();
423 423
424 removeElementFromDocumentMap(this, &document()); 424 removeElementFromDocumentMap(this, &document());
425 #endif 425 #endif
426 426
427 // Destroying the player may cause a resource load to be canceled, 427 // Destroying the player may cause a resource load to be canceled,
428 // which could result in userCancelledLoad() being called back. 428 // which could result in userCancelledLoad() being called back.
429 // Setting m_completelyLoaded ensures that such a call will not cause 429 // Setting m_completelyLoaded ensures that such a call will not cause
430 // us to dispatch an abort event, which would result in a crash. 430 // us to dispatch an abort event, which would result in a crash.
431 // See http://crbug.com/233654 for more details. 431 // See http://crbug.com/233654 for more details.
432 m_completelyLoaded = true; 432 m_completelyLoaded = true;
433 433
434 // With Oilpan load events on the Document are always delayed during 434 // With Oilpan load events on the Document are always delayed during
435 // sweeping so we don't need to explicitly increment and decrement 435 // sweeping so we don't need to explicitly increment and decrement
436 // load event delay counts. 436 // load event delay counts.
437 #if !ENABLE(OILPAN) 437 #if !ENABLE(OILPAN)
438 // Destroying the player may cause a resource load to be canceled, 438 // Destroying the player may cause a resource load to be canceled,
439 // which could result in Document::dispatchWindowLoadEvent() being 439 // which could result in Document::dispatchWindowLoadEvent() being
440 // called via ResourceFetch::didLoadResource() then 440 // called via ResourceFetch::didLoadResource() then
441 // FrameLoader::checkCompleted(). To prevent load event dispatching during 441 // FrameLoader::checkCompleted(). To prevent load event dispatching during
442 // object destruction, we use Document::incrementLoadEventDelayCount(). 442 // object destruction, we use Document::incrementLoadEventDelayCount().
443 // See http://crbug.com/275223 for more details. 443 // See http://crbug.com/275223 for more details.
444 document().incrementLoadEventDelayCount(); 444 document().incrementLoadEventDelayCount();
445 #endif 445 #endif
446 446
447 #if ENABLE(OILPAN)
448 // Oilpan: the player must be released, but the player object
449 // cannot safely access this player client any longer as parts of
450 // it may have been finalized already (like the media element's
451 // supplementable table.) Handled for now by entering an
452 // is-finalizing state, which is explicitly checked for if the
453 // player tries to access the media element during shutdown.
454 //
455 // FIXME: Oilpan: move the media player to the heap instead and
456 // avoid having to finalize it from here; this whole #if block
457 // could then be removed (along with the state bit it depends on.)
458 // crbug.com/378229
459 m_isFinalizing = true;
460 #endif
461
462 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). 447 // m_audioSourceNode is explicitly cleared by AudioNode::dispose().
463 // Since AudioNode::dispose() is guaranteed to be always called before 448 // Since AudioNode::dispose() is guaranteed to be always called before
464 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared 449 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared
465 // even if the AudioNode and the HTMLMediaElement die together. 450 // even if the AudioNode and the HTMLMediaElement die together.
466 #if ENABLE(WEB_AUDIO) 451 #if ENABLE(WEB_AUDIO)
467 ASSERT(!m_audioSourceNode); 452 ASSERT(!m_audioSourceNode);
468 #endif 453 #endif
469 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); 454 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
470 455
471 #if !ENABLE(OILPAN) 456 #if !ENABLE(OILPAN)
472 document().decrementLoadEventDelayCount(); 457 document().decrementLoadEventDelayCount();
473 #endif 458 #endif
474 } 459 }
475 460
476 #if ENABLE(OILPAN) 461 #if ENABLE(OILPAN)
462 void HTMLMediaElement::dispose()
463 {
464 // If the HTMLMediaElement dies with the Document we are not
465 // allowed to touch the Document to adjust delay load event counts
466 // from the destructor, as the Document could have been already
467 // destructed.
468 //
469 // Work around that restriction by accessing the Document from
470 // a prefinalizer action instead, updating its delayed load count.
471 // If needed - if the Document has been detached and informed its
472 // ContextLifecycleObservers (which HTMLMediaElement is) that
473 // it is being destroyed, the connection to the Document will
474 // have been severed already, but in that case there is no need
475 // to update the delayed load count. But if the Document hasn't
476 // been detached cleanly from any frame or it isn't dying in the
477 // same GC, we do update the delayed load count from the prefinalizer.
478 if (ActiveDOMObject::executionContext())
479 setShouldDelayLoadEvent(false);
480 }
481
477 void HTMLMediaElement::setCloseMediaSourceWhenFinalizing() 482 void HTMLMediaElement::setCloseMediaSourceWhenFinalizing()
478 { 483 {
479 ASSERT(!m_closeMediaSourceWhenFinalizing); 484 ASSERT(!m_closeMediaSourceWhenFinalizing);
480 m_closeMediaSourceWhenFinalizing = true; 485 m_closeMediaSourceWhenFinalizing = true;
481 } 486 }
482 #endif 487 #endif
483 488
484 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) 489 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument)
485 { 490 {
486 WTF_LOG(Media, "HTMLMediaElement::didMoveToNewDocument(%p)", this); 491 WTF_LOG(Media, "HTMLMediaElement::didMoveToNewDocument(%p)", this);
(...skipping 3180 matching lines...) Expand 10 before | Expand all | Expand 10 after
3667 3672
3668 #if ENABLE(WEB_AUDIO) 3673 #if ENABLE(WEB_AUDIO)
3669 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) 3674 void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
3670 { 3675 {
3671 if (!Heap::isHeapObjectAlive(m_audioSourceNode) && audioSourceProvider()) 3676 if (!Heap::isHeapObjectAlive(m_audioSourceNode) && audioSourceProvider())
3672 audioSourceProvider()->setClient(nullptr); 3677 audioSourceProvider()->setClient(nullptr);
3673 } 3678 }
3674 #endif 3679 #endif
3675 3680
3676 } 3681 }
OLDNEW
« no previous file with comments | « Source/core/html/HTMLMediaElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698