summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-23 17:39:53 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-23 17:39:53 +0000
commitdb2fb782473f73581430e16df9b1bd8b15e8e85c (patch)
tree7e3a3a0234a2484b3ef1a313f7fde72da8ab4b17 /chrome/browser/renderer_host
parentf1cd5e88af6f0d088d7b90a8f4b69da63aa994af (diff)
downloadchromium_src-db2fb782473f73581430e16df9b1bd8b15e8e85c.zip
chromium_src-db2fb782473f73581430e16df9b1bd8b15e8e85c.tar.gz
chromium_src-db2fb782473f73581430e16df9b1bd8b15e8e85c.tar.bz2
When sending resources across the IPC barrier, use increasing sized buffers.
AsyncResourceHandler::OnWillRead will usually allocate a new piece of shared memory for each 32 kilobyte chunk of a resource to be sent over IPC from the browser to the renderer. Instead, use a 32k chunk, then a 64k chunk, then a 128k chunk up to a maximum size of 512k. Why? Because transferring large resources is really slow. To send a sequence of 32k chunks to the renderer, we need to wait for the renderer to send an ACK message back before we send the next chunk. The themeing on the new tab page is a pathological case for this code. Most of the background images are large, and my test case is about 800k. This was 25 round trips. Now it is 5. According to the web inspector, it used to take ~700ms to transfer said image. Now it's in the ~30ms range. It feels faster, and the web inspector shows the speed up, but tab_complex_theme_cold does not... BUG=http://crbug.com/24493 TEST=Doesn't regress any performance tests. Review URL: http://codereview.chromium.org/331001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29904 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/async_resource_handler.cc40
-rw-r--r--chrome/browser/renderer_host/async_resource_handler.h6
2 files changed, 38 insertions, 8 deletions
diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc
index 95852be..da188b6 100644
--- a/chrome/browser/renderer_host/async_resource_handler.cc
+++ b/chrome/browser/renderer_host/async_resource_handler.cc
@@ -10,15 +10,28 @@
#include "chrome/common/render_messages.h"
#include "net/base/io_buffer.h"
+namespace {
+
// When reading, we don't know if we are going to get EOF (0 bytes read), so
// we typically have a buffer that we allocated but did not use. We keep
// this buffer around for the next read as a small optimization.
-static SharedIOBuffer* g_spare_read_buffer = NULL;
+SharedIOBuffer* g_spare_read_buffer = NULL;
+
+// The initial size of the shared memory buffer. (32 kilobytes).
+const int kReadBufSize = 32768;
+
+// The maximum size of the shared memory buffer. (512 kilobytes).
+const int kMaxBufSize = 524288;
+
+} // namespace
// Our version of IOBuffer that uses shared memory.
class SharedIOBuffer : public net::IOBuffer {
public:
- SharedIOBuffer(int buffer_size) : net::IOBuffer(), ok_(false) {
+ SharedIOBuffer(int buffer_size)
+ : net::IOBuffer(),
+ ok_(false),
+ buffer_size_(buffer_size) {
if (shared_memory_.Create(std::wstring(), false, false, buffer_size) &&
shared_memory_.Map(buffer_size)) {
ok_ = true;
@@ -33,10 +46,12 @@ class SharedIOBuffer : public net::IOBuffer {
base::SharedMemory* shared_memory() { return &shared_memory_; }
bool ok() { return ok_; }
+ int buffer_size() { return buffer_size_; }
private:
base::SharedMemory shared_memory_;
bool ok_;
+ int buffer_size_;
};
AsyncResourceHandler::AsyncResourceHandler(
@@ -50,7 +65,8 @@ AsyncResourceHandler::AsyncResourceHandler(
process_id_(process_id),
routing_id_(routing_id),
process_handle_(process_handle),
- rdh_(resource_dispatcher_host) {
+ rdh_(resource_dispatcher_host),
+ next_buffer_size_(kReadBufSize) {
}
bool AsyncResourceHandler::OnUploadProgress(int request_id,
@@ -80,21 +96,29 @@ bool AsyncResourceHandler::OnResponseStarted(int request_id,
bool AsyncResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf,
int* buf_size, int min_size) {
DCHECK(min_size == -1);
- static const int kReadBufSize = 32768;
+
if (g_spare_read_buffer) {
DCHECK(!read_buffer_);
read_buffer_.swap(&g_spare_read_buffer);
// TODO(willchan): Remove after debugging bug 16371.
CHECK(read_buffer_->data());
+
+ *buf = read_buffer_.get();
+ *buf_size = read_buffer_.get()->buffer_size();
} else {
- read_buffer_ = new SharedIOBuffer(kReadBufSize);
- if (!read_buffer_->ok())
+ read_buffer_ = new SharedIOBuffer(next_buffer_size_);
+ if (!read_buffer_->ok()) {
+ DLOG(ERROR) << "Couldn't allocate shared io buffer";
return false;
+ }
// TODO(willchan): Remove after debugging bug 16371.
CHECK(read_buffer_->data());
+ *buf = read_buffer_.get();
+ *buf_size = next_buffer_size_;
}
- *buf = read_buffer_.get();
- *buf_size = kReadBufSize;
+
+ next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxBufSize);
+
return true;
}
diff --git a/chrome/browser/renderer_host/async_resource_handler.h b/chrome/browser/renderer_host/async_resource_handler.h
index 17e9260..b946d4d 100644
--- a/chrome/browser/renderer_host/async_resource_handler.h
+++ b/chrome/browser/renderer_host/async_resource_handler.h
@@ -46,6 +46,12 @@ class AsyncResourceHandler : public ResourceHandler {
base::ProcessHandle process_handle_;
ResourceDispatcherHost* rdh_;
+ // We exponentially grow the size of the buffer allocated. On the first
+ // OnWillRead() call, we allocate a buffer of 32k and double it on each
+ // subsequent call, up to a maximum size of 512k. |next_buffer_size_| is the
+ // size of the buffer to be allocated on the next OnWillRead() call.
+ int next_buffer_size_;
+
DISALLOW_COPY_AND_ASSIGN(AsyncResourceHandler);
};