OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/base/contiguous_container.h" | 5 #include "cc/base/contiguous_container.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 namespace cc { | 11 namespace cc { |
12 | 12 |
13 // Default number of max-sized elements to allocate space for, if there is no | 13 // Default number of max-sized elements to allocate space for, if there is no |
14 // initial buffer. | 14 // initial buffer. |
15 static const unsigned kDefaultInitialBufferSize = 32; | 15 static const unsigned kDefaultInitialBufferSize = 32; |
16 | 16 |
17 class ContiguousContainerBase::Buffer { | 17 class ContiguousContainerBase::Buffer { |
18 public: | 18 public: |
19 explicit Buffer(size_t buffer_size) | 19 explicit Buffer(size_t buffer_size) : end_(nullptr), capacity_(buffer_size) {} |
20 : data_(new char[buffer_size]), end_(begin()), capacity_(buffer_size) {} | |
21 | 20 |
22 ~Buffer() {} | 21 ~Buffer() {} |
23 | 22 |
24 size_t Capacity() const { return capacity_; } | 23 size_t Capacity() const { return capacity_; } |
25 size_t UsedCapacity() const { return end_ - begin(); } | 24 size_t UsedCapacity() const { return end_ - begin(); } |
26 size_t UnusedCapacity() const { return Capacity() - UsedCapacity(); } | 25 size_t UnusedCapacity() const { return Capacity() - UsedCapacity(); } |
| 26 size_t MemoryUsage() const { return begin() ? capacity_ : 0; } |
27 bool empty() const { return UsedCapacity() == 0; } | 27 bool empty() const { return UsedCapacity() == 0; } |
28 | 28 |
29 void* Allocate(size_t object_size) { | 29 void* Allocate(size_t object_size) { |
30 DCHECK_GE(UnusedCapacity(), object_size); | 30 DCHECK_GE(UnusedCapacity(), object_size); |
| 31 if (!data_) { |
| 32 data_.reset(new char[capacity_]); |
| 33 end_ = begin(); |
| 34 } |
31 void* result = end_; | 35 void* result = end_; |
32 end_ += object_size; | 36 end_ += object_size; |
33 return result; | 37 return result; |
34 } | 38 } |
35 | 39 |
36 void DeallocateLastObject(void* object) { | 40 void DeallocateLastObject(void* object) { |
37 DCHECK_LE(begin(), object); | 41 DCHECK_LE(begin(), object); |
38 DCHECK_LT(object, end_); | 42 DCHECK_LT(object, end_); |
39 end_ = static_cast<char*>(object); | 43 end_ = static_cast<char*>(object); |
40 } | 44 } |
41 | 45 |
42 private: | 46 private: |
43 char* begin() { return &data_[0]; } | 47 char* begin() { return data_.get(); } |
44 const char* begin() const { return &data_[0]; } | 48 const char* begin() const { return data_.get(); } |
45 | 49 |
46 // begin() <= end_ <= begin() + capacity_ | 50 // begin() <= end_ <= begin() + capacity_ |
47 std::unique_ptr<char[]> data_; | 51 std::unique_ptr<char[]> data_; |
48 char* end_; | 52 char* end_; |
49 size_t capacity_; | 53 size_t capacity_; |
50 }; | 54 }; |
51 | 55 |
52 ContiguousContainerBase::ContiguousContainerBase(size_t max_object_size) | 56 ContiguousContainerBase::ContiguousContainerBase(size_t max_object_size) |
53 : end_index_(0), max_object_size_(max_object_size) {} | 57 : end_index_(0), max_object_size_(max_object_size) {} |
54 | 58 |
(...skipping 14 matching lines...) Expand all Loading... |
69 } | 73 } |
70 | 74 |
71 size_t ContiguousContainerBase::UsedCapacityInBytes() const { | 75 size_t ContiguousContainerBase::UsedCapacityInBytes() const { |
72 size_t used_capacity = 0; | 76 size_t used_capacity = 0; |
73 for (const auto& buffer : buffers_) | 77 for (const auto& buffer : buffers_) |
74 used_capacity += buffer->UsedCapacity(); | 78 used_capacity += buffer->UsedCapacity(); |
75 return used_capacity; | 79 return used_capacity; |
76 } | 80 } |
77 | 81 |
78 size_t ContiguousContainerBase::MemoryUsageInBytes() const { | 82 size_t ContiguousContainerBase::MemoryUsageInBytes() const { |
79 return sizeof(*this) + GetCapacityInBytes() + | 83 size_t memory_usage = 0; |
| 84 for (const auto& buffer : buffers_) |
| 85 memory_usage += buffer->MemoryUsage(); |
| 86 return sizeof(*this) + memory_usage + |
80 elements_.capacity() * sizeof(elements_[0]); | 87 elements_.capacity() * sizeof(elements_[0]); |
81 } | 88 } |
82 | 89 |
83 void* ContiguousContainerBase::Allocate(size_t object_size) { | 90 void* ContiguousContainerBase::Allocate(size_t object_size) { |
84 DCHECK_LE(object_size, max_object_size_); | 91 DCHECK_LE(object_size, max_object_size_); |
85 | 92 |
86 Buffer* buffer_for_alloc = nullptr; | 93 Buffer* buffer_for_alloc = nullptr; |
87 if (!buffers_.empty()) { | 94 if (!buffers_.empty()) { |
88 Buffer* end_buffer = buffers_[end_index_].get(); | 95 Buffer* end_buffer = buffers_[end_index_].get(); |
89 if (end_buffer->UnusedCapacity() >= object_size) | 96 if (end_buffer->UnusedCapacity() >= object_size) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 size_t buffer_size) { | 144 size_t buffer_size) { |
138 DCHECK(buffers_.empty() || end_index_ == buffers_.size() - 1); | 145 DCHECK(buffers_.empty() || end_index_ == buffers_.size() - 1); |
139 std::unique_ptr<Buffer> new_buffer(new Buffer(buffer_size)); | 146 std::unique_ptr<Buffer> new_buffer(new Buffer(buffer_size)); |
140 Buffer* buffer_to_return = new_buffer.get(); | 147 Buffer* buffer_to_return = new_buffer.get(); |
141 buffers_.push_back(std::move(new_buffer)); | 148 buffers_.push_back(std::move(new_buffer)); |
142 end_index_ = buffers_.size() - 1; | 149 end_index_ = buffers_.size() - 1; |
143 return buffer_to_return; | 150 return buffer_to_return; |
144 } | 151 } |
145 | 152 |
146 } // namespace cc | 153 } // namespace cc |
OLD | NEW |