From 43a9e24a52fa867db98fc2195b8db85b4729e7a1 Mon Sep 17 00:00:00 2001 From: "tommi@chromium.org" Date: Wed, 6 Apr 2011 17:42:45 +0000 Subject: Switch out use of std::string and std::vector for large allocations for a buffer class that doesn't throw exceptions. The new buffer class is pretty simple and relies on the MemoryAllocator class that I previously to back large allocations with mapped files when memory is scarce. That reduced the number of crashes quite a bit but we still crash on machines that are simply out of diskspace as well. So, the right thing to do is to expect and handle failures which is what this cl is all about. What we should see once this has landed is that crash dumps due to courgette running out of disk space should disappear from crash/ and instead we should see the number of users that run into this particular problem in dashboards. TEST=Courgette out-of-memory/out-of-diskspace errors should disappear from crash/ BUG=74777 Review URL: http://codereview.chromium.org/6677141 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80648 0039d316-1c4b-4281-b951-d872f2087c98 --- courgette/assembly_program.cc | 60 ++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'courgette/assembly_program.cc') diff --git a/courgette/assembly_program.cc b/courgette/assembly_program.cc index 080a89e..f759e16 100644 --- a/courgette/assembly_program.cc +++ b/courgette/assembly_program.cc @@ -86,8 +86,7 @@ class InstructionWithLabel : public Instruction { } // namespace AssemblyProgram::AssemblyProgram() - : byte_instruction_cache_(NULL), - image_base_(0) { + : image_base_(0) { } static void DeleteContainedLabels(const RVAToLabel& labels) { @@ -101,33 +100,32 @@ AssemblyProgram::~AssemblyProgram() { if (instruction->op() != DEFBYTE) // Will be in byte_instruction_cache_. delete instruction; } - if (byte_instruction_cache_) { + if (byte_instruction_cache_.get()) { for (size_t i = 0; i < 256; ++i) delete byte_instruction_cache_[i]; - delete[] byte_instruction_cache_; } DeleteContainedLabels(rel32_labels_); DeleteContainedLabels(abs32_labels_); } -void AssemblyProgram::EmitMakeRelocsInstruction() { - Emit(new MakeRelocsInstruction()); +CheckBool AssemblyProgram::EmitMakeRelocsInstruction() { + return Emit(new(std::nothrow) MakeRelocsInstruction()); } -void AssemblyProgram::EmitOriginInstruction(RVA rva) { - Emit(new OriginInstruction(rva)); +CheckBool AssemblyProgram::EmitOriginInstruction(RVA rva) { + return Emit(new(std::nothrow) OriginInstruction(rva)); } -void AssemblyProgram::EmitByteInstruction(uint8 byte) { - Emit(GetByteInstruction(byte)); +CheckBool AssemblyProgram::EmitByteInstruction(uint8 byte) { + return Emit(GetByteInstruction(byte)); } -void AssemblyProgram::EmitRel32(Label* label) { - Emit(new InstructionWithLabel(REL32, label)); +CheckBool AssemblyProgram::EmitRel32(Label* label) { + return Emit(new(std::nothrow) InstructionWithLabel(REL32, label)); } -void AssemblyProgram::EmitAbs32(Label* label) { - Emit(new InstructionWithLabel(ABS32, label)); +CheckBool AssemblyProgram::EmitAbs32(Label* label) { + return Emit(new(std::nothrow) InstructionWithLabel(ABS32, label)); } Label* AssemblyProgram::FindOrMakeAbs32Label(RVA rva) { @@ -167,10 +165,19 @@ Label* AssemblyProgram::InstructionRel32Label( return NULL; } +CheckBool AssemblyProgram::Emit(Instruction* instruction) { + if (!instruction) + return false; + bool ok = instructions_.push_back(instruction); + if (!ok) + delete instruction; + return ok; +} + Label* AssemblyProgram::FindLabel(RVA rva, RVAToLabel* labels) { Label*& slot = (*labels)[rva]; - if (slot == 0) { - slot = new Label(rva); + if (slot == NULL) { + slot = new(std::nothrow) Label(rva); } return slot; } @@ -307,7 +314,10 @@ static CheckBool DefineLabels(const RVAToLabel& labels, } EncodedProgram* AssemblyProgram::Encode() const { - scoped_ptr encoded(new EncodedProgram()); + scoped_ptr encoded(new(std::nothrow) EncodedProgram()); + if (!encoded.get()) + return NULL; + encoded->set_image_base(image_base_); if (!DefineLabels(abs32_labels_, encoded.get(), @@ -362,10 +372,20 @@ EncodedProgram* AssemblyProgram::Encode() const { } Instruction* AssemblyProgram::GetByteInstruction(uint8 byte) { - if (!byte_instruction_cache_) { - byte_instruction_cache_ = new Instruction*[256]; + if (!byte_instruction_cache_.get()) { + byte_instruction_cache_.reset(new(std::nothrow) Instruction*[256]); + if (!byte_instruction_cache_.get()) + return NULL; + for (int i = 0; i < 256; ++i) { - byte_instruction_cache_[i] = new ByteInstruction(static_cast(i)); + byte_instruction_cache_[i] = + new(std::nothrow) ByteInstruction(static_cast(i)); + if (!byte_instruction_cache_[i]) { + for (int j = 0; j < i; ++j) + delete byte_instruction_cache_[j]; + byte_instruction_cache_.reset(); + return NULL; + } } } -- cgit v1.1