Index: courgette/patch_generator_x86_32.h |
diff --git a/courgette/patch_generator_x86_32.h b/courgette/patch_generator_x86_32.h |
index b03d7c15759468f188faad35ee3dd6c8e602d449..90ef5d49f27034994c5d25c7b2febb403e4a41e3 100644 |
--- a/courgette/patch_generator_x86_32.h |
+++ b/courgette/patch_generator_x86_32.h |
@@ -9,11 +9,9 @@ |
#include "base/logging.h" |
#include "base/macros.h" |
-#include "courgette/assembly_program.h" |
#include "courgette/courgette_flow.h" |
#include "courgette/ensemble.h" |
#include "courgette/patcher_x86_32.h" |
-#include "courgette/program_detector.h" |
namespace courgette { |
@@ -51,11 +49,14 @@ class PatchGeneratorX86_32 : public TransformationPatchGenerator { |
return C_OK; |
} |
- // The format of a transformed_element is a serialized EncodedProgram. We |
- // first disassemble the original old and new Elements into AssemblyPrograms. |
- // Then we adjust the new AssemblyProgram to make it as much like the old one |
- // as possible, before converting the AssemblyPrograms to EncodedPrograms and |
- // serializing them. |
+ // The format of a transformed_element is a serialized EncodedProgram. Steps: |
+ // - Form Disassembler for the old and new Elements. |
+ // - Extract AssemblyPrograms from old and new Disassemblers. |
+ // - Adjust the new AssemblyProgram to make it as much like the old one as |
+ // possible. |
+ // - Serialize old and new Disassembler to EncodedProgram, using the old |
+ // AssemblyProgram and the adjusted new AssemblyProgram. |
+ // The steps are performed in an order to reduce peak memory. |
Status Transform(SourceStreamSet* corrected_parameters, |
SinkStreamSet* old_transformed_element, |
SinkStreamSet* new_transformed_element) { |
@@ -63,21 +64,32 @@ class PatchGeneratorX86_32 : public TransformationPatchGenerator { |
if (!corrected_parameters->Empty()) |
return C_GENERAL_ERROR; |
+ // Flow graph and process sequence (DA = Disassembler, AP = AssemblyProgram, |
+ // EP = EncodedProgram, Adj = Adjusted): |
+ // [1 Old DA] --> [2 Old AP] [6 New AP] <-- [5 New DA] |
+ // | | | | | |
+ // v | | v (move) v |
+ // [3 Old EP] <-----+ +->[7 Adj New AP] --> [8 New EP] |
+ // (4 Write) (9 Write) |
CourgetteFlow flow; |
RegionBuffer old_buffer(old_element_->region()); |
RegionBuffer new_buffer(new_element_->region()); |
- flow.ReadAssemblyProgramFromBuffer(flow.OLD, old_buffer, true); |
- flow.CreateEncodedProgramFromAssemblyProgram(flow.OLD); |
+ flow.ReadDisassemblerFromBuffer(flow.OLD, old_buffer); // 1 |
+ flow.CreateAssemblyProgramFromDisassembler(flow.OLD, true); // 2 |
+ flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.OLD); // 3 |
+ flow.DestroyDisassembler(flow.OLD); |
flow.WriteSinkStreamSetFromEncodedProgram(flow.OLD, |
- old_transformed_element); |
+ old_transformed_element); // 4 |
flow.DestroyEncodedProgram(flow.OLD); |
- flow.ReadAssemblyProgramFromBuffer(flow.NEW, new_buffer, true); |
- flow.AdjustNewAssemblyProgramToMatchOld(); |
+ flow.ReadDisassemblerFromBuffer(flow.NEW, new_buffer); // 5 |
+ flow.CreateAssemblyProgramFromDisassembler(flow.NEW, true); // 6 |
+ flow.AdjustNewAssemblyProgramToMatchOld(); // 7 |
flow.DestroyAssemblyProgram(flow.OLD); |
- flow.CreateEncodedProgramFromAssemblyProgram(flow.NEW); |
+ flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.NEW); // 8 |
flow.DestroyAssemblyProgram(flow.NEW); |
+ flow.DestroyDisassembler(flow.NEW); |
flow.WriteSinkStreamSetFromEncodedProgram(flow.NEW, |
- new_transformed_element); |
+ new_transformed_element); // 9 |
if (flow.failed()) { |
LOG(ERROR) << flow.message() << " (" << old_element_->Name() << " => " |
<< new_element_->Name() << ")"; |