diff --git a/courgette/adjustment_method_unittest.cc b/courgette/adjustment_method_unittest.cc index 3200f10c60994..d8b987c2d89e1 100644 --- a/courgette/adjustment_method_unittest.cc +++ b/courgette/adjustment_method_unittest.cc @@ -5,11 +5,13 @@ #include #include #include +#include #include "base/strings/string_util.h" #include "courgette/assembly_program.h" #include "courgette/courgette.h" #include "courgette/encoded_program.h" +#include "courgette/image_utils.h" #include "courgette/streams.h" #include "testing/gtest/include/gtest/gtest.h" @@ -32,8 +34,20 @@ class AdjustmentMethodTest : public testing::Test { new courgette::AssemblyProgram(courgette::EXE_WIN_32_X86)); prog->set_image_base(0x00400000); - courgette::Label* labelA = prog->FindOrMakeAbs32Label(0x00410000); - courgette::Label* labelB = prog->FindOrMakeAbs32Label(0x00410004); + courgette::RVA kRvaA = 0x00410000; + courgette::RVA kRvaB = 0x00410004; + + std::vector abs32_rvas; + abs32_rvas.push_back(kRvaA); + abs32_rvas.push_back(kRvaB); + std::vector rel32_rvas; // Stub. + + courgette::TrivialRvaVisitor abs32_visitor(abs32_rvas); + courgette::TrivialRvaVisitor rel32_visitor(rel32_rvas); + prog->PrecomputeLabels(&abs32_visitor, &rel32_visitor); + + courgette::Label* labelA = prog->FindAbs32Label(kRvaA); + courgette::Label* labelB = prog->FindAbs32Label(kRvaB); EXPECT_TRUE(prog->EmitAbs32(labelA)); EXPECT_TRUE(prog->EmitAbs32(labelA)); @@ -88,7 +102,6 @@ class AdjustmentMethodTest : public testing::Test { } }; - void AdjustmentMethodTest::Test1() const { std::unique_ptr prog1 = MakeProgramA(); std::unique_ptr prog2 = MakeProgramB(); @@ -109,7 +122,6 @@ void AdjustmentMethodTest::Test1() const { EXPECT_TRUE(s5 == s6); // Adjustment did change B into A } - TEST_F(AdjustmentMethodTest, All) { Test1(); } diff --git a/courgette/assembly_program.cc b/courgette/assembly_program.cc index 5344cff95f848..f20ed67ea3fa3 100644 --- a/courgette/assembly_program.cc +++ b/courgette/assembly_program.cc @@ -111,11 +111,6 @@ AssemblyProgram::AssemblyProgram(ExecutableType kind) : kind_(kind), image_base_(0) { } -static void DeleteContainedLabels(const RVAToLabel& labels) { - for (RVAToLabel::const_iterator p = labels.begin(); p != labels.end(); ++p) - UncheckedDelete(p->second); -} - AssemblyProgram::~AssemblyProgram() { for (size_t i = 0; i < instructions_.size(); ++i) { Instruction* instruction = instructions_[i]; @@ -126,8 +121,6 @@ AssemblyProgram::~AssemblyProgram() { for (size_t i = 0; i < 256; ++i) UncheckedDelete(byte_instruction_cache_[i]); } - DeleteContainedLabels(rel32_labels_); - DeleteContainedLabels(abs32_labels_); } CheckBool AssemblyProgram::EmitPeRelocsInstruction() { @@ -178,27 +171,50 @@ CheckBool AssemblyProgram::EmitAbs64(Label* label) { ScopedInstruction(UncheckedNew(ABS64, label))); } -Label* AssemblyProgram::FindOrMakeAbs32Label(RVA rva) { - return FindLabel(rva, &abs32_labels_); +void AssemblyProgram::PrecomputeLabels(RvaVisitor* abs32_visitor, + RvaVisitor* rel32_visitor) { + abs32_label_manager_.Read(abs32_visitor); + rel32_label_manager_.Read(rel32_visitor); + TrimLabels(); } -Label* AssemblyProgram::FindOrMakeRel32Label(RVA rva) { - return FindLabel(rva, &rel32_labels_); -} +// Chosen empirically to give the best reduction in payload size for +// an update from daisy_3701.98.0 to daisy_4206.0.0. +const int AssemblyProgram::kLabelLowerLimit = 5; -void AssemblyProgram::DefaultAssignIndexes() { - DefaultAssignIndexes(&abs32_labels_); - DefaultAssignIndexes(&rel32_labels_); +void AssemblyProgram::TrimLabels() { + // For now only trim for ARM binaries. + if (kind() != EXE_ELF_32_ARM) + return; + + int lower_limit = kLabelLowerLimit; + + VLOG(1) << "TrimLabels: threshold " << lower_limit; + + rel32_label_manager_.RemoveUnderusedLabels(lower_limit); } void AssemblyProgram::UnassignIndexes() { - UnassignIndexes(&abs32_labels_); - UnassignIndexes(&rel32_labels_); + abs32_label_manager_.UnassignIndexes(); + rel32_label_manager_.UnassignIndexes(); +} + +void AssemblyProgram::DefaultAssignIndexes() { + abs32_label_manager_.DefaultAssignIndexes(); + rel32_label_manager_.DefaultAssignIndexes(); } void AssemblyProgram::AssignRemainingIndexes() { - AssignRemainingIndexes(&abs32_labels_); - AssignRemainingIndexes(&rel32_labels_); + abs32_label_manager_.AssignRemainingIndexes(); + rel32_label_manager_.AssignRemainingIndexes(); +} + +Label* AssemblyProgram::FindAbs32Label(RVA rva) { + return abs32_label_manager_.Find(rva); +} + +Label* AssemblyProgram::FindRel32Label(RVA rva) { + return rel32_label_manager_.Find(rva); } Label* AssemblyProgram::InstructionAbs32Label( @@ -238,17 +254,6 @@ CheckBool AssemblyProgram::EmitShared(Instruction* instruction) { return instruction && instructions_.push_back(instruction); } -Label* AssemblyProgram::FindLabel(RVA rva, RVAToLabel* labels) { - Label*& slot = (*labels)[rva]; - if (slot == NULL) { - slot = UncheckedNew