diff options
Diffstat (limited to 'courgette')
-rw-r--r-- | courgette/encoded_program.cc | 10 | ||||
-rw-r--r-- | courgette/memory_allocator.h | 10 |
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_; } |