From fbd31eb81436cf7f6d4f9ea3683c100f112361e6 Mon Sep 17 00:00:00 2001 From: "tommi@chromium.org" Date: Tue, 1 Mar 2011 00:19:02 +0000 Subject: Implementation of an STL compatible allocator for Courgette on Windows. This is to better handle low memory situations when applying a differential patch to a large Chrome setup. For reading input files, I'm also switching to using memory mapped files instead of ReadFileToString to reduce the load on the heap. TEST=courgette.exe should succeed in applying a patch between two chrome 10.x archives on an XP machine with 180MB of physical memory and no page file. BUG=72459,73209 Review URL: http://codereview.chromium.org/6597038 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76320 0039d316-1c4b-4281-b951-d872f2087c98 --- courgette/encoded_program.cc | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'courgette/encoded_program.cc') diff --git a/courgette/encoded_program.cc b/courgette/encoded_program.cc index f09a350..8439d31 100644 --- a/courgette/encoded_program.cc +++ b/courgette/encoded_program.cc @@ -39,18 +39,19 @@ EncodedProgram::EncodedProgram() : image_base_(0) {} EncodedProgram::~EncodedProgram() {} // Serializes a vector of integral values using Varint32 coding. -template -void WriteVector(const std::vector& items, SinkStream* buffer) { +template +void WriteVector(const std::vector& items, SinkStream* buffer) { size_t count = items.size(); buffer->WriteSizeVarint32(count); for (size_t i = 0; i < count; ++i) { - COMPILE_ASSERT(sizeof(T) <= sizeof(uint32), T_must_fit_in_uint32); + COMPILE_ASSERT(sizeof(T) <= sizeof(uint32), // NOLINT + T_must_fit_in_uint32); buffer->WriteSizeVarint32(items[i]); } } -template -bool ReadVector(std::vector* items, SourceStream* buffer) { +template +bool ReadVector(std::vector* items, SourceStream* buffer) { uint32 count; if (!buffer->ReadVarint32(&count)) return false; @@ -68,7 +69,8 @@ bool ReadVector(std::vector* items, SourceStream* buffer) { } // Serializes a vector, using delta coding followed by Varint32 coding. -void WriteU32Delta(const std::vector& set, SinkStream* buffer) { +template +void WriteU32Delta(const std::vector& set, SinkStream* buffer) { size_t count = set.size(); buffer->WriteSizeVarint32(count); uint32 prev = 0; @@ -80,7 +82,8 @@ void WriteU32Delta(const std::vector& set, SinkStream* buffer) { } } -static bool ReadU32Delta(std::vector* set, SourceStream* buffer) { +template +static bool ReadU32Delta(std::vector* set, SourceStream* buffer) { uint32 count; if (!buffer->ReadVarint32(&count)) @@ -109,8 +112,8 @@ static bool ReadU32Delta(std::vector* set, SourceStream* buffer) { // the possibility of a greater size for experiments comparing Varint32 encoding // of a vector of larger integrals vs a plain form.) // -template -void WriteVectorU8(const std::vector& items, SinkStream* buffer) { +template +void WriteVectorU8(const std::vector& items, SinkStream* buffer) { size_t count = items.size(); buffer->WriteSizeVarint32(count); if (count != 0) { @@ -119,8 +122,8 @@ void WriteVectorU8(const std::vector& items, SinkStream* buffer) { } } -template -bool ReadVectorU8(std::vector* items, SourceStream* buffer) { +template +bool ReadVectorU8(std::vector* items, SourceStream* buffer) { uint32 count; if (!buffer->ReadVarint32(&count)) return false; @@ -146,7 +149,7 @@ void EncodedProgram::DefineAbs32Label(int index, RVA value) { static const RVA kUnassignedRVA = static_cast(-1); -void EncodedProgram::DefineLabelCommon(std::vector* rvas, +void EncodedProgram::DefineLabelCommon(RvaVector* rvas, int index, RVA rva) { if (static_cast(rvas->size()) <= index) { @@ -163,7 +166,7 @@ void EncodedProgram::EndLabels() { FinishLabelsCommon(&rel32_rva_); } -void EncodedProgram::FinishLabelsCommon(std::vector* rvas) { +void EncodedProgram::FinishLabelsCommon(RvaVector* rvas) { // Replace all unassigned slots with the value at the previous index so they // delta-encode to zero. (There might be better values than zero. The way to // get that is have the higher level assembly program assign the unassigned @@ -183,7 +186,7 @@ void EncodedProgram::AddOrigin(RVA origin) { origins_.push_back(origin); } -void EncodedProgram::AddCopy(int count, const void* bytes) { +void EncodedProgram::AddCopy(uint32 count, const void* bytes) { const uint8* source = static_cast(bytes); // Fold adjacent COPY instructions into one. This nearly halves the size of @@ -199,7 +202,7 @@ void EncodedProgram::AddCopy(int count, const void* bytes) { } if (ops_.back() == COPY) { copy_counts_.back() += count; - for (int i = 0; i < count; ++i) { + for (uint32 i = 0; i < count; ++i) { copy_bytes_.push_back(source[i]); } return; @@ -212,7 +215,7 @@ void EncodedProgram::AddCopy(int count, const void* bytes) { } else { ops_.push_back(COPY); copy_counts_.push_back(count); - for (int i = 0; i < count; ++i) { + for (uint32 i = 0; i < count; ++i) { copy_bytes_.push_back(source[i]); } } @@ -349,8 +352,8 @@ bool EncodedProgram::ReadFrom(SourceStreamSet* streams) { // Safe, non-throwing version of std::vector::at(). Returns 'true' for success, // 'false' for out-of-bounds index error. -template -bool VectorAt(const std::vector& v, size_t index, T* output) { +template +bool VectorAt(const std::vector& v, size_t index, T* output) { if (index >= v.size()) return false; *output = v[index]; @@ -390,11 +393,11 @@ bool EncodedProgram::AssembleTo(SinkStream* final_buffer) { } case COPY: { - int count; + uint32 count; if (!VectorAt(copy_counts_, ix_copy_counts, &count)) return false; ++ix_copy_counts; - for (int i = 0; i < count; ++i) { + for (uint32 i = 0; i < count; ++i) { uint8 b; if (!VectorAt(copy_bytes_, ix_copy_bytes, &b)) return false; -- cgit v1.1