| Index: courgette/assembly_program.cc
 | 
| diff --git a/courgette/assembly_program.cc b/courgette/assembly_program.cc
 | 
| index fdd312a585a53cf2edac8cce01dbe26ee339d42a..531b6850730f4466fbbabde16d7e7ce74bc829e4 100644
 | 
| --- a/courgette/assembly_program.cc
 | 
| +++ b/courgette/assembly_program.cc
 | 
| @@ -7,6 +7,7 @@
 | 
|  #include "base/callback.h"
 | 
|  #include "base/logging.h"
 | 
|  #include "courgette/courgette.h"
 | 
| +#include "courgette/disassembler.h"
 | 
|  #include "courgette/encoded_program.h"
 | 
|  
 | 
|  namespace courgette {
 | 
| @@ -104,10 +105,10 @@ class InstructionCountReceptor : public InstructionReceptor {
 | 
|   public:
 | 
|    InstructionCountReceptor() = default;
 | 
|  
 | 
| -  size_t size() const { return size_; }
 | 
| +  size_t abs_count() const { return abs_count_; }
 | 
| +  size_t rel_count() const { return rel_count_; }
 | 
|  
 | 
|    // InstructionReceptor:
 | 
| -  // TODO(huangs): 2016/11: Populate these with size_ += ...
 | 
|    CheckBool EmitPeRelocs() override { return true; }
 | 
|    CheckBool EmitElfRelocation() override { return true; }
 | 
|    CheckBool EmitElfARMRelocation() override { return true; }
 | 
| @@ -116,18 +117,29 @@ class InstructionCountReceptor : public InstructionReceptor {
 | 
|    CheckBool EmitMultipleBytes(const uint8_t* bytes, size_t len) override {
 | 
|      return true;
 | 
|    }
 | 
| -  CheckBool EmitRel32(Label* label) override { return true; }
 | 
| +  CheckBool EmitRel32(Label* label) override {
 | 
| +    ++rel_count_;
 | 
| +    return true;
 | 
| +  }
 | 
|    CheckBool EmitRel32ARM(uint16_t op,
 | 
|                           Label* label,
 | 
|                           const uint8_t* arm_op,
 | 
|                           uint16_t op_size) override {
 | 
| +    ++rel_count_;
 | 
| +    return true;
 | 
| +  }
 | 
| +  CheckBool EmitAbs32(Label* label) override {
 | 
| +    ++abs_count_;
 | 
| +    return true;
 | 
| +  }
 | 
| +  CheckBool EmitAbs64(Label* label) override {
 | 
| +    ++abs_count_;
 | 
|      return true;
 | 
|    }
 | 
| -  CheckBool EmitAbs32(Label* label) override { return true; }
 | 
| -  CheckBool EmitAbs64(Label* label) override { return true; }
 | 
|  
 | 
|   private:
 | 
| -  size_t size_ = 0;
 | 
| +  size_t abs_count_ = 0;
 | 
| +  size_t rel_count_ = 0;
 | 
|  
 | 
|    DISALLOW_COPY_AND_ASSIGN(InstructionCountReceptor);
 | 
|  };
 | 
| @@ -137,15 +149,15 @@ class InstructionCountReceptor : public InstructionReceptor {
 | 
|  // An InstructionReceptor that stores emitted instructions.
 | 
|  class InstructionStoreReceptor : public InstructionReceptor {
 | 
|   public:
 | 
| -  explicit InstructionStoreReceptor(AssemblyProgram* program)
 | 
| -      : program_(program) {
 | 
| +  InstructionStoreReceptor(AssemblyProgram* program, bool annotate_labels)
 | 
| +      : program_(program), annotate_labels_(annotate_labels) {
 | 
|      CHECK(program_);
 | 
|    }
 | 
|  
 | 
| -  // TODO(huangs): 2016/11: Add Reserve().
 | 
| +  // TODO(huangs): 2017/04: Add Reserve().
 | 
|  
 | 
|    // InstructionReceptor:
 | 
| -  // TODO(huangs): 2016/11: Replace stub with implementation.
 | 
| +  // TODO(huangs): 2017/04: Move implementations here.
 | 
|    CheckBool EmitPeRelocs() override { return program_->EmitPeRelocs(); }
 | 
|    CheckBool EmitElfRelocation() override {
 | 
|      return program_->EmitElfRelocation();
 | 
| @@ -161,23 +173,32 @@ class InstructionStoreReceptor : public InstructionReceptor {
 | 
|      return program_->EmitMultipleBytes(bytes, len);
 | 
|    }
 | 
|    CheckBool EmitRel32(Label* label) override {
 | 
| +    if (annotate_labels_)
 | 
| +      program_->mutable_rel32_label_annotations()->push_back(label);
 | 
|      return program_->EmitRel32(label);
 | 
|    }
 | 
|    CheckBool EmitRel32ARM(uint16_t op,
 | 
|                           Label* label,
 | 
|                           const uint8_t* arm_op,
 | 
|                           uint16_t op_size) override {
 | 
| +    if (annotate_labels_)
 | 
| +      program_->mutable_rel32_label_annotations()->push_back(label);
 | 
|      return program_->EmitRel32ARM(op, label, arm_op, op_size);
 | 
|    }
 | 
|    CheckBool EmitAbs32(Label* label) override {
 | 
| +    if (annotate_labels_)
 | 
| +      program_->mutable_abs32_label_annotations()->push_back(label);
 | 
|      return program_->EmitAbs32(label);
 | 
|    }
 | 
|    CheckBool EmitAbs64(Label* label) override {
 | 
| +    if (annotate_labels_)
 | 
| +      program_->mutable_abs32_label_annotations()->push_back(label);
 | 
|      return program_->EmitAbs64(label);
 | 
|    }
 | 
|  
 | 
|   private:
 | 
|    AssemblyProgram* program_;
 | 
| +  const bool annotate_labels_;
 | 
|  
 | 
|    DISALLOW_COPY_AND_ASSIGN(InstructionStoreReceptor);
 | 
|  };
 | 
| @@ -294,28 +315,24 @@ Label* AssemblyProgram::FindRel32Label(RVA rva) {
 | 
|    return rel32_label_manager_.Find(rva);
 | 
|  }
 | 
|  
 | 
| -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<const InstructionWithLabel*>(instruction)->label());
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -CheckBool AssemblyProgram::GenerateInstructions(
 | 
| -    const InstructionGenerator& gen) {
 | 
| -  // Pass 1: Count the space needed to store instructions.
 | 
| +CheckBool AssemblyProgram::GenerateInstructions(const InstructionGenerator& gen,
 | 
| +                                                bool annotate_labels) {
 | 
| +  // Pass 1: Count storage space required and reserve in advance.
 | 
|    InstructionCountReceptor count_receptor;
 | 
|    if (!gen.Run(&count_receptor))
 | 
|      return false;
 | 
|  
 | 
| -  // Pass 2: Emit all instructions to preallocated buffer (uses Phase 1 count).
 | 
| -  InstructionStoreReceptor store_receptor(this);
 | 
| -  // TODO(huangs): 2017/03: Pass |count_receptor->size()| to |store_receptor_|
 | 
| -  // to reserve space for raw data.
 | 
| +  if (annotate_labels) {
 | 
| +    DCHECK(abs32_label_annotations_.empty());
 | 
| +    abs32_label_annotations_.reserve(count_receptor.abs_count());
 | 
| +    DCHECK(rel32_label_annotations_.empty());
 | 
| +    rel32_label_annotations_.reserve(count_receptor.rel_count());
 | 
| +  }
 | 
| +
 | 
| +  // Pass 2: Emit all instructions to reserved buffer (uses Phase 1 count).
 | 
| +  // Populates |abs32_label_annotations_| and |re32_label_annotations_| if
 | 
| +  // |annotate_labels| is true.
 | 
| +  InstructionStoreReceptor store_receptor(this, annotate_labels);
 | 
|    return gen.Run(&store_receptor);
 | 
|  }
 | 
|  
 | 
| 
 |