diff --git a/courgette/adjustment_method.cc b/courgette/adjustment_method.cc index ce93a21a87b3bc..d6718bc8d919ad 100644 --- a/courgette/adjustment_method.cc +++ b/courgette/adjustment_method.cc @@ -14,6 +14,7 @@ #include #include +#include "base/bind.h" #include "base/logging.h" #include "base/macros.h" #include "base/strings/string_number_conversions.h" @@ -592,17 +593,19 @@ class GraphAdjuster : public AdjustmentMethod { } private: - void CollectTraces(const AssemblyProgram* program, Trace* abs32, Trace* rel32, bool is_model) { - const InstructionVector& instructions = program->instructions(); - for (size_t i = 0; i < instructions.size(); ++i) { - Instruction* instruction = instructions[i]; - if (Label* label = program->InstructionAbs32Label(instruction)) - ReferenceLabel(abs32, label, is_model); - if (Label* label = program->InstructionRel32Label(instruction)) - ReferenceLabel(rel32, label, is_model); - } + AssemblyProgram::LabelHandler abs32_handler = + base::Bind(&GraphAdjuster::ReferenceLabel, base::Unretained(this), + abs32, is_model); + AssemblyProgram::LabelHandler rel32_handler = + base::Bind(&GraphAdjuster::ReferenceLabel, base::Unretained(this), + rel32, is_model); + + program->HandleInstructionLabels({{ABS32, abs32_handler}, + {REL32, rel32_handler}, + {REL32ARM, rel32_handler}}); + // TODO(sra): we could simply append all the labels in index order to // incorporate some costing for entropy (bigger deltas) that will be // introduced into the label address table by non-monotonic ordering. This @@ -634,7 +637,7 @@ class GraphAdjuster : public AdjustmentMethod { } } - void ReferenceLabel(Trace* trace, Label* label, bool is_model) { + void ReferenceLabel(Trace* trace, bool is_model, Label* label) { trace->push_back( MakeLabelInfo(label, is_model, static_cast(trace->size()))); } diff --git a/courgette/adjustment_method_2.cc b/courgette/adjustment_method_2.cc index d783cdac810799..b5fbb7c610fabe 100644 --- a/courgette/adjustment_method_2.cc +++ b/courgette/adjustment_method_2.cc @@ -15,6 +15,7 @@ #include #include +#include "base/bind.h" #include "base/format_macros.h" #include "base/logging.h" #include "base/macros.h" @@ -1252,16 +1253,17 @@ class Adjuster : public AdjustmentMethod { void CollectTraces(const AssemblyProgram* program, Trace* abs32, Trace* rel32, bool is_model) { label_info_maker_.ResetDebugLabel(); - const InstructionVector& instructions = program->instructions(); - for (size_t i = 0; i < instructions.size(); ++i) { - Instruction* instruction = instructions[i]; - if (Label* label = program->InstructionAbs32Label(instruction)) - ReferenceLabel(abs32, label, is_model); - if (Label* label = program->InstructionAbs64Label(instruction)) - ReferenceLabel(abs32, label, is_model); - if (Label* label = program->InstructionRel32Label(instruction)) - ReferenceLabel(rel32, label, is_model); - } + + AssemblyProgram::LabelHandler abs32_handler = base::Bind( + &Adjuster::ReferenceLabel, base::Unretained(this), abs32, is_model); + AssemblyProgram::LabelHandler rel32_handler = base::Bind( + &Adjuster::ReferenceLabel, base::Unretained(this), rel32, is_model); + + program->HandleInstructionLabels({{ABS32, abs32_handler}, + {ABS64, abs32_handler}, + {REL32, rel32_handler}, + {REL32ARM, rel32_handler}}); + // TODO(sra): we could simply append all the labels in index order to // incorporate some costing for entropy (bigger deltas) that will be // introduced into the label address table by non-monotonic ordering. This @@ -1277,7 +1279,7 @@ class Adjuster : public AdjustmentMethod { << (base::Time::Now() - start_time).InSecondsF(); } - void ReferenceLabel(Trace* trace, Label* label, bool is_model) { + void ReferenceLabel(Trace* trace, bool is_model, Label* label) { trace->push_back(label_info_maker_.MakeLabelInfo( label, is_model, static_cast(trace->size()))); } diff --git a/courgette/assembly_program.cc b/courgette/assembly_program.cc index f20ed67ea3fa3e..d36556fc67ad4e 100644 --- a/courgette/assembly_program.cc +++ b/courgette/assembly_program.cc @@ -217,28 +217,15 @@ Label* AssemblyProgram::FindRel32Label(RVA rva) { return rel32_label_manager_.Find(rva); } -Label* AssemblyProgram::InstructionAbs32Label( - const Instruction* instruction) const { - if (instruction->op() == ABS32) - return static_cast(instruction)->label(); - return NULL; -} - -Label* AssemblyProgram::InstructionAbs64Label( - const Instruction* instruction) const { - if (instruction->op() == ABS64) - return static_cast(instruction)->label(); - return NULL; -} - -Label* AssemblyProgram::InstructionRel32Label( - const Instruction* instruction) const { - if (instruction->op() == REL32 || instruction->op() == REL32ARM) { - Label* label = - static_cast(instruction)->label(); - return label; +void AssemblyProgram::HandleInstructionLabels( + const AssemblyProgram::LabelHandlerMap& handler_map) const { + for (const Instruction* instruction : instructions_) { + LabelHandlerMap::const_iterator it = handler_map.find(instruction->op()); + if (it != handler_map.end()) { + it->second.Run( + static_cast(instruction)->label()); + } } - return NULL; } CheckBool AssemblyProgram::Emit(ScopedInstruction instruction) { diff --git a/courgette/assembly_program.h b/courgette/assembly_program.h index 96d6dafe356767..50ab30a6f6cac9 100644 --- a/courgette/assembly_program.h +++ b/courgette/assembly_program.h @@ -13,6 +13,7 @@ #include #include +#include "base/bind.h" #include "base/macros.h" #include "base/memory/free_deleter.h" #include "courgette/courgette.h" @@ -79,6 +80,9 @@ typedef NoThrowBuffer InstructionVector; // class AssemblyProgram { public: + using LabelHandler = base::Callback; + using LabelHandlerMap = std::map; + explicit AssemblyProgram(ExecutableType kind); ~AssemblyProgram(); @@ -142,22 +146,11 @@ class AssemblyProgram { std::unique_ptr Encode() const; - // Accessor for instruction list. - const InstructionVector& instructions() const { - return instructions_; - } - - // Returns the label if the instruction contains an absolute 32-bit address, - // otherwise returns NULL. - Label* InstructionAbs32Label(const Instruction* instruction) const; - - // Returns the label if the instruction contains an absolute 64-bit address, - // otherwise returns NULL. - Label* InstructionAbs64Label(const Instruction* instruction) const; - - // Returns the label if the instruction contains a rel32 offset, - // otherwise returns NULL. - Label* InstructionRel32Label(const Instruction* instruction) const; + // For each |instruction| in |instructions_|, looks up its opcode from + // |handler_map| for a handler. If a handler exists, invoke it by passing the + // |instruction|'s label. We assume that |handler_map| has correct keys, i.e., + // opcodes for an instruction that have label. + void HandleInstructionLabels(const LabelHandlerMap& handler_map) const; private: using ScopedInstruction =