summaryrefslogtreecommitdiffstats
path: root/webkit/glue
diff options
context:
space:
mode:
authorenal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-20 05:06:37 +0000
committerenal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-20 05:06:37 +0000
commit38aefc31753a9a6d302358f8cb3968eca10d0cd3 (patch)
treede0faf86da01498a26513c830c923ac65f952834 /webkit/glue
parent48a62cd798aa251fb37afa929b391117454d7d38 (diff)
downloadchromium_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.cc41
-rw-r--r--webkit/glue/webmediaplayer_impl.h32
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);
};