Commit 86e68d02 authored by Kanghua Yu's avatar Kanghua Yu Committed by Commit Bot

[turbofan] Add verification for jump optimization.

The jump optimization maybe run Turbofan pipeline twice for each TF/CS builtins,
and relies on the fact that the number of j/jmp instruction generated is always
the same.
This CL introduces a verification process to ensure that instruction sequence
and virtual registers are always the same in two stages, before the final
code generation phase.

R=danno@chromium.org, jarin@chromium.org

Bug: v8:7839
Change-Id: Id77e9bc80f54f79d7a845315e0b99e3f4b6a54fb
Reviewed-on: https://chromium-review.googlesource.com/1100491
Commit-Queue: Kanghua Yu <kanghua.yu@intel.com>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53774}
parent ee94d9be
......@@ -79,12 +79,17 @@ class JumpOptimizationInfo {
bool is_optimizable() const { return optimizable_; }
void set_optimizable() { optimizable_ = true; }
// Used to verify the instruction sequence is always the same in two stages.
size_t hash_code() const { return hash_code_; }
void set_hash_code(size_t hash_code) { hash_code_ = hash_code; }
std::vector<uint32_t>& farjmp_bitmap() { return farjmp_bitmap_; }
private:
enum { kCollection, kOptimization } stage_ = kCollection;
bool optimizable_ = false;
std::vector<uint32_t> farjmp_bitmap_;
size_t hash_code_ = 0u;
};
class HeapObjectRequest {
......
......@@ -487,6 +487,7 @@ class PipelineImpl final {
// Step D. Run the code finalization pass.
Handle<Code> FinalizeCode();
void VerifyGeneratedCodeIsIdempotent();
void RunPrintAndVerify(const char* phase, bool untyped = false);
Handle<Code> GenerateCode(CallDescriptor* call_descriptor);
void AllocateRegisters(const RegisterConfiguration* config,
......@@ -2340,6 +2341,9 @@ bool PipelineImpl::SelectInstructions(Linkage* linkage) {
run_verifier);
}
// Verify the instruction sequence has the same hash in two stages.
VerifyGeneratedCodeIsIdempotent();
Run<FrameElisionPhase>();
if (data->compilation_failed()) {
info()->AbortOptimization(
......@@ -2361,6 +2365,29 @@ bool PipelineImpl::SelectInstructions(Linkage* linkage) {
return true;
}
void PipelineImpl::VerifyGeneratedCodeIsIdempotent() {
PipelineData* data = this->data_;
JumpOptimizationInfo* jump_opt = data->jump_optimization_info();
if (jump_opt == nullptr) return;
InstructionSequence* code = data->sequence();
int instruction_blocks = code->InstructionBlockCount();
int virtual_registers = code->VirtualRegisterCount();
size_t hash_code = base::hash_combine(instruction_blocks, virtual_registers);
for (auto instr : *code) {
hash_code = base::hash_combine(hash_code, instr->opcode(),
instr->InputCount(), instr->OutputCount());
}
for (int i = 0; i < virtual_registers; i++) {
hash_code = base::hash_combine(hash_code, code->GetRepresentation(i));
}
if (jump_opt->is_collecting()) {
jump_opt->set_hash_code(hash_code);
} else {
CHECK_EQ(hash_code, jump_opt->hash_code());
}
}
struct InstructionStartsAsJSON {
const ZoneVector<int>* instr_starts;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment