perf(relinker): write in-place --to-intel substitutions directly
Each in-place substitution went through X64InstructionRewriter::Rewrite, which copies the whole code segment and decodes every instruction in it to adjust references. The converter only accepts equal-length replacements, so the adjustment is always zero and the copy and scan are wasted: conversion time grew by one segment scan per substitution. Copy the replacement bytes into the segment instead.
This commit is contained in:
parent
9619edff72
commit
2daa034e87
|
|
@ -3,7 +3,6 @@
|
|||
#include <codegen/CodegenException.hpp>
|
||||
#include <codegen/x86/Amd64OnlySubstitutionTable.hpp>
|
||||
#include <codegen/x86/X64InstructionDecoder.hpp>
|
||||
#include <codegen/x86/X64InstructionRewriter.hpp>
|
||||
#include <codegen/x86/IAmd64OnlyInstructionMatcher.hpp>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
|
@ -39,7 +38,6 @@ private:
|
|||
Amd64OnlyMatch Substitution;
|
||||
};
|
||||
|
||||
X64InstructionRewriter _rewriter;
|
||||
std::unique_ptr<IAmd64OnlyInstructionMatcher> _matcher = MakeAmd64OnlyInstructionMatcher();
|
||||
std::unique_ptr<IInstructionScanner> _scanner = MakeInstructionScanner();
|
||||
|
||||
|
|
@ -120,7 +118,7 @@ void Amd64OnlyConverter::_convertSegment(
|
|||
case Amd64OnlyLowering::InPlace: {
|
||||
if (substitution.ReplacementBytes.size() != match.Length)
|
||||
throw CodegenException("Intel substitution changes the instruction length", fileOffset);
|
||||
seg = _atFileOffset(ph.Offset, [&] { return _rewriter.Rewrite(seg, {match.Offset, substitution.ReplacementBytes}).Bytes; });
|
||||
std::copy(substitution.ReplacementBytes.begin(), substitution.ReplacementBytes.end(), seg.begin() + static_cast<std::ptrdiff_t>(match.Offset));
|
||||
replacementLength = substitution.ReplacementBytes.size();
|
||||
++result.ReplacedCount;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue