summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--courgette/encoded_program.cc10
-rw-r--r--courgette/memory_allocator.h10
2 files changed, 13 insertions, 7 deletions
diff --git a/courgette/encoded_program.cc b/courgette/encoded_program.cc
index 0253894..a4c0089 100644
--- a/courgette/encoded_program.cc
+++ b/courgette/encoded_program.cc
@@ -145,7 +145,15 @@ CheckBool EncodedProgram::DefineLabelCommon(RvaVector* rvas,
int index,
RVA rva) {
bool ok = true;
- if (static_cast<int>(rvas->size()) <= index)
+
+ // Resize |rvas| to accommodate |index|. If we naively call resize(), in the
+ // worst case we'd encounter |index| in increasing order, and then we'd
+ // require reallocation every time. Turns out this worst case is the typical
+ // scenario, and noticeable slowness (~5x slow down) ensues. The solution is
+ // to exponentially increase capacity. We use a factor of 1.01 to be frugal.
+ if (static_cast<int>(rvas->capacity()) <= index)
+ ok = rvas->reserve((index + 1) * 1.01);
+ if (ok && static_cast<int>(rvas->size()) <= index)
ok = rvas->resize(index + 1, kUnassignedRVA);
if (ok) {
diff --git a/courgette/memory_allocator.h b/courgette/memory_allocator.h
index 7161592..59d3ec8 100644
--- a/courgette/memory_allocator.h
+++ b/courgette/memory_allocator.h
@@ -363,12 +363,6 @@ class NoThrowBuffer {
if (size < kStartSize)
size = kStartSize;
- // Use a size 1% higher than requested. In practice, this makes Courgette as
- // much as 5x faster on typical Chrome update payloads as a lot of future
- // reserve() calls will become no-ops instead of costly resizes that copy
- // all the data. Note that doing this here instead of outside the function
- // is more efficient, since it's after the no-op early return checks above.
- size *= 1.01;
T* new_buffer = alloc_.allocate(size);
if (!new_buffer) {
clear();
@@ -485,6 +479,10 @@ class NoThrowBuffer {
return size_;
}
+ size_t capacity() const {
+ return alloc_size_;
+ }
+
T* data() const {
return buffer_;
}