New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 635142 link

Starred by 2 users

Issue metadata

Status: Fixed
Owner:
Last visit 15 days ago
Closed: Oct 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 3
Type: Bug

Blocking:
issue 634696



Sign in to add a comment

Defer allocation in ContiguousContainerBase::Buffer

Project Member Reported by dskiba@chromium.org, Aug 5 2016

Issue description

As part of identifying redundant allocations in Chrome, I found that memory allocated by ContiguousContainerBase::Buffer::Buffer() sometimes is not really used, resulting in 98 KiB of zeroes (14 * 7200), see https://docs.google.com/spreadsheets/d/1HfHKXy4q-ytZ-nwPay8YYyVSn1o-X9I7cWzYlygvtwQ/edit#gid=167958829

Backtrace misses some calls (because of inlining), but here is what happens (Android, 32-bit):

* DisplayItemList::Inputs::Inputs() creates ContiguousContainerBase object with the second argument of 7200 (LargestDisplayItemSize() * kDefaultNumDisplayItemsToReserve = 72 * 100)
* ContiguousContainerBase::ContiguousContainerBase() calls AllocateNewBufferForNextAllocation() with 7200
* AllocateNewBufferForNextAllocation() creates ContiguousContainerBase::Buffer() with 7200
* ContiguousContainerBase::Buffer() allocates 7200 bytes
* In some cases preallocated Buffer object is never written to (via Allocate()), and its data_ remains blob of zeroes

I'm proposing deferring allocation of Buffer::data_ until it's really needed, i.e. until the first Buffer::Allocate() call. The change is simple:

diff --git a/cc/base/contiguous_container.cc b/cc/base/contiguous_container.cc
index d6280b4..6439ceb 100644
--- a/cc/base/contiguous_container.cc
+++ b/cc/base/contiguous_container.cc
@@ -17,7 +17,7 @@ static const unsigned kDefaultInitialBufferSize = 32;
 class ContiguousContainerBase::Buffer {
  public:
   explicit Buffer(size_t buffer_size)
-      : data_(new char[buffer_size]), end_(begin()), capacity_(buffer_size) {}
+      : end_(nullptr), capacity_(buffer_size) {}
 
   ~Buffer() {}
 
@@ -28,6 +28,10 @@ class ContiguousContainerBase::Buffer {
 
   void* Allocate(size_t object_size) {
     DCHECK_GE(UnusedCapacity(), object_size);
+    if (!data_) {
+      data_.reset(new char[capacity_]);
+      end_ = begin();
+    }
     void* result = end_;
     end_ += object_size;
     return result;
@@ -40,8 +44,8 @@ class ContiguousContainerBase::Buffer {
   }
 
  private:
-  char* begin() { return &data_[0]; }
-  const char* begin() const { return &data_[0]; }
+  char* begin() { return data_.get(); }
+  const char* begin() const { return data_.get(); }
 
   // begin() <= end_ <= begin() + capacity_
   std::unique_ptr<char[]> data_;


(More info about the effort to kill redundant allocations is here: https://groups.google.com/a/chromium.org/forum/#!msg/project-trim/EiKXwnbTvbo/0z-Y5Kg1CgAJ)
 
Blocking: 634696

Comment 2 by dskiba@chromium.org, Aug 18 2016

Cc: aelias@chromium.org
PTAL

Comment 3 by aelias@chromium.org, Aug 18 2016

Cc: danakj@chromium.org

Comment 4 by danakj@chromium.org, Aug 18 2016

Cc: weiliangc@chromium.org jbroman@chromium.org

Comment 5 by danakj@chromium.org, Aug 18 2016

Seems okay to me along as iterating it before/after Allocate works correctly.

Comment 6 by danakj@chromium.org, Aug 18 2016

Owner: dskiba@chromium.org
Status: Assigned (was: Untriaged)
You wanna send a patch for it? Can you ensure it's unit tested for the above?

Comment 7 by dskiba@chromium.org, Aug 18 2016

OK, I'll send a patch (and a test) a bit later.
Equivalent changes to blink::ContiguousContainer, if applicable, would be appreciated.
Project Member

Comment 9 by bugdroid1@chromium.org, Aug 24 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/aa339ecad2407a5b3875dc597843b1634cec5445

commit aa339ecad2407a5b3875dc597843b1634cec5445
Author: dskiba <dskiba@google.com>
Date: Wed Aug 24 23:53:03 2016

Defer allocation in cc::ContiguousContainerBase::Buffer.

This CL optimizes memory usage of cc::ContiguousContainer by deferring memory
allocation in ContiguousContainerBase::Buffer until the first Allocate() call.
Previously memory was allocated in the Buffer constructor, and sometimes was
never written to (see the bug for more info).

BUG= 635142 
CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_precise_blink_rel

Review-Url: https://codereview.chromium.org/2277433002
Cr-Commit-Position: refs/heads/master@{#414204}

[modify] https://crrev.com/aa339ecad2407a5b3875dc597843b1634cec5445/cc/base/contiguous_container.cc
[modify] https://crrev.com/aa339ecad2407a5b3875dc597843b1634cec5445/cc/base/contiguous_container_unittest.cc

Is this fixed?
Status: Fixed (was: Assigned)
Blink has similar class, and similar fix can be applied, but it my testing I never saw it having zero memory, and I don't have time now. So marking this as fixed.

Sign in to add a comment