diff options
author | enal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-20 05:06:37 +0000 |
---|---|---|
committer | enal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-20 05:06:37 +0000 |
commit | 38aefc31753a9a6d302358f8cb3968eca10d0cd3 (patch) | |
tree | de0faf86da01498a26513c830c923ac65f952834 /webkit/glue | |
parent | 48a62cd798aa251fb37afa929b391117454d7d38 (diff) | |
download | chromium_src-38aefc31753a9a6d302358f8cb3968eca10d0cd3.zip chromium_src-38aefc31753a9a6d302358f8cb3968eca10d0cd3.tar.gz chromium_src-38aefc31753a9a6d302358f8cb3968eca10d0cd3.tar.bz2 |
Tell JS heap that audio player object uses lot of native memory.
BUG=http://code.google.com/p/chromium/issues/detail?id=61293
BUG=http://code.google.com/p/chromium/issues/detail?id=78992
BUG=http://code.google.com/p/chromium/issues/detail?id=95230
Review URL: http://codereview.chromium.org/7923019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101918 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/webmediaplayer_impl.cc | 41 | ||||
-rw-r--r-- | webkit/glue/webmediaplayer_impl.h | 32 |
2 files changed, 73 insertions, 0 deletions
diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc index e77ed36..76e6437 100644 --- a/webkit/glue/webmediaplayer_impl.cc +++ b/webkit/glue/webmediaplayer_impl.cc @@ -28,6 +28,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h" +#include "v8/include/v8.h" #include "webkit/glue/media/buffered_data_source.h" #include "webkit/glue/media/simple_data_source.h" #include "webkit/glue/media/media_stream_client.h" @@ -43,6 +44,16 @@ using media::PipelineStatus; namespace { +// Amount of extra memory used by each player instance reported to V8. +// It is not exact number -- first, it differs on different platforms, +// and second, it is very hard to calculate. Instead, use some arbitrary +// value that will cause garbage collection from time to time. We don't want +// it to happen on every allocation, but don't want 5k players to sit in memory +// either. Looks that chosen constant achieves both goals, at least for audio +// objects. (Do not worry about video objects yet, JS programs do not create +// thousands of them...) +const int kPlayerExtraMemory = 1024 * 1024; + // Limits the range of playback rate. // // TODO(kylep): Revisit these. @@ -123,6 +134,19 @@ bool WebMediaPlayerImpl::Initialize( return false; } + // Let V8 know we started new thread if we did not did it yet. + // Made separate task to avoid deletion of player currently being created. + // Also, delaying GC until after player starts gets rid of starting lag -- + // collection happens in parallel with playing. + // TODO(enal): remove when we get rid of per-audio-stream thread. + if (destructor_or_task_had_run_.get() == NULL) { + destructor_or_task_had_run_ = new DestructorOrTaskHadRun(); + main_loop_->PostTask( + FROM_HERE, + NewRunnableFunction(WebMediaPlayerImpl::UsesExtraMemoryTask, + destructor_or_task_had_run_)); + } + pipeline_ = new media::PipelineImpl(pipeline_message_loop, media_log_); // Also we want to be notified of |main_loop_| destruction. @@ -817,6 +841,15 @@ void WebMediaPlayerImpl::Destroy() { media::PipelineStatusNotification note; pipeline_->Stop(note.Callback()); note.Wait(); + + // Let V8 know we are not using extra resources anymore. + if (destructor_or_task_had_run_.get() != NULL) { + if (destructor_or_task_had_run_->value()) + v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory); + else + destructor_or_task_had_run_->set_value(true); + } + destructor_or_task_had_run_ = NULL; } message_loop_factory_.reset(); @@ -835,4 +868,12 @@ WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { return client_; } +void WebMediaPlayerImpl::UsesExtraMemoryTask( + scoped_refptr<DestructorOrTaskHadRun> destructor_or_task_had_run) { + if (!destructor_or_task_had_run->value()) { + v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); + destructor_or_task_had_run->set_value(true); + } +} + } // namespace webkit_glue diff --git a/webkit/glue/webmediaplayer_impl.h b/webkit/glue/webmediaplayer_impl.h index 1b2d8be..7d0ce41 100644 --- a/webkit/glue/webmediaplayer_impl.h +++ b/webkit/glue/webmediaplayer_impl.h @@ -196,6 +196,32 @@ class WebMediaPlayerImpl void OnDemuxerOpened(); private: + // Class used to avoid race condition: + // * We added task UsesExtraMemoryTask to tell the V8 we are using extra + // memory. + // * Meanwhile, WebMediaPlayerImpl is being deleted. We want to let V8 know + // we are not using that extra memory anymore -- but we cannot be sure + // UsesExtraMemoryTask was yet completed. We cannot add task doing that to + // the message loop either, because we will break shutodown of some tests + // that wait till queue is empty and don't expect destructor to add new + // tasks. + // We also don't want to delay destruction of WebMediaPlayerImpl till + // UsesExtraMemoryTask finishes, as object is big and uses lot of resources. + // + // Solution is to use small ref counted object that usually has 2 references + // to it -- one from WebMediaPlayerImpl, and one from message loop. Destructor + // and UsesExtraMemoryTask can communicate through it. + class DestructorOrTaskHadRun: + public base::RefCounted<DestructorOrTaskHadRun> { + public: + DestructorOrTaskHadRun() : value_(false) { } + bool value() const { return value_; } + void set_value(bool value) { value_ = value; } + + private: + bool value_; + }; + // Helpers that set the network/ready state and notifies the client if // they've changed. void SetNetworkState(WebKit::WebMediaPlayer::NetworkState state); @@ -207,6 +233,10 @@ class WebMediaPlayerImpl // Getter method to |client_|. WebKit::WebMediaPlayerClient* GetClient(); + // Lets V8 know that player uses extra resources not managed by V8. + static void UsesExtraMemoryTask( + scoped_refptr<DestructorOrTaskHadRun> destructor_or_task_had_run); + // TODO(hclam): get rid of these members and read from the pipeline directly. WebKit::WebMediaPlayer::NetworkState network_state_; WebKit::WebMediaPlayer::ReadyState ready_state_; @@ -260,6 +290,8 @@ class WebMediaPlayerImpl scoped_refptr<media::MediaLog> media_log_; + scoped_refptr<DestructorOrTaskHadRun> destructor_or_task_had_run_; + DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl); }; |