Commit e3ae8a31 authored by Pierre Langlois's avatar Pierre Langlois Committed by Commit Bot

[arm64][turbofan] Optimize bailout check.

Every JS function has a bailout check at the beginning which makes sure it was
not lazily deoptimized. We can improve the check slightly:

- Load the code data container directly with a pc-relative load instead of
  ADR+LDR.
- Check the deoptimization bit with TBZ directly, saving us a TST instruction.
- Use one of the macro-assembler's dedicated scratch registers instead of x2.

Bug: 
Change-Id: Iea4824c74ed5a01b18595d5e980788f9745bbb6e
Reviewed-on: https://chromium-review.googlesource.com/864446Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Pierre Langlois <pierre.langlois@arm.com>
Cr-Commit-Position: refs/heads/master@{#50570}
parent 7ac10da7
......@@ -538,24 +538,34 @@ void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
// Check if the code object is marked for deoptimization. If it is, then it
// jumps to the CompileLazyDeoptimizedCode builtin. In order to do this we need
// to:
// 1. load the address of the current instruction;
// 1. compute the offset of the {CodeDataContainer} from our current location
// and load it.
// 2. read from memory the word that contains that bit, which can be found in
// the flags in the referenced {CodeDataContainer} object;
// 3. test kMarkedForDeoptimizationBit in those flags; and
// 4. if it is not zero then it jumps to the builtin.
void CodeGenerator::BailoutIfDeoptimized() {
Label current;
// The Adr instruction gets the address of the current instruction.
__ Adr(x2, &current);
__ Bind(&current);
int pc = __ pc_offset();
int offset = Code::kCodeDataContainerOffset - (Code::kHeaderSize + pc);
__ Ldr(x2, MemOperand(x2, offset));
__ Ldr(x2, FieldMemOperand(x2, CodeDataContainer::kKindSpecificFlagsOffset));
__ Tst(x2, Immediate(1 << Code::kMarkedForDeoptimizationBit));
UseScratchRegisterScope temps(tasm());
Register scratch = temps.AcquireX();
{
// Since we always emit a bailout check at the very beginning we can be
// certain that the distance between here and the {CodeDataContainer} is
// fixed and always in range of a load.
int data_container_offset =
(Code::kCodeDataContainerOffset - Code::kHeaderSize) - __ pc_offset();
DCHECK_GE(0, data_container_offset);
DCHECK_EQ(0, data_container_offset % 4);
InstructionAccurateScope scope(tasm());
__ ldr_pcrel(scratch, data_container_offset >> 2);
}
__ Ldr(scratch,
FieldMemOperand(scratch, CodeDataContainer::kKindSpecificFlagsOffset));
Label not_deoptimized;
__ Tbz(scratch, Code::kMarkedForDeoptimizationBit, &not_deoptimized);
Handle<Code> code = isolate()->builtins()->builtin_handle(
Builtins::kCompileLazyDeoptimizedCode);
__ Jump(code, RelocInfo::CODE_TARGET, ne);
__ Jump(code, RelocInfo::CODE_TARGET);
__ Bind(&not_deoptimized);
}
// Assembles an instruction after register allocation, producing machine code.
......
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