Always emit unconditional jump in binary-search switch
We probably expect a binary-search switch to take log(n) time in all cases, but there is currently a possibility of that expectation being broken. I'm not aware of any place where this actually happens, but if the default handler immediately follows the switch dispatch block in assembly order, then unconditional jump instructions for that handler would be omitted. This omission could cause linear execution time, where every case is checked before falling through to the default handler. This change introduces a new function to emit an unconditional jump instruction regardless of whether the target is the following block, and uses that new function when generating a binary-search switch to ensure consistently log(n) behavior. Change-Id: I5cab86fd66386762519035410e3b532dc6fd764c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3335222 Reviewed-by: Nico Hartmann <nicohartmann@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/main@{#78370}
This commit is contained in:
parent
dad520133c
commit
dd9d4c96c1
@ -3548,8 +3548,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
AssembleArchBranch(instr, branch);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ b(GetLabel(target));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
@ -2905,8 +2905,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
AssembleArchBranch(instr, branch);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ B(GetLabel(target));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
@ -498,7 +498,7 @@ void CodeGenerator::AssembleArchBinarySearchSwitchRange(
|
||||
tasm()->JumpIfEqual(input, begin->first, begin->second);
|
||||
++begin;
|
||||
}
|
||||
AssembleArchJump(def_block);
|
||||
AssembleArchJumpRegardlessOfAssemblyOrder(def_block);
|
||||
return;
|
||||
}
|
||||
auto middle = begin + (end - begin) / 2;
|
||||
@ -509,6 +509,11 @@ void CodeGenerator::AssembleArchBinarySearchSwitchRange(
|
||||
AssembleArchBinarySearchSwitchRange(input, def_block, begin, middle);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target))
|
||||
AssembleArchJumpRegardlessOfAssemblyOrder(target);
|
||||
}
|
||||
|
||||
base::OwnedVector<byte> CodeGenerator::GetSourcePositionTable() {
|
||||
return source_position_table_builder_.ToSourcePositionTableVector();
|
||||
}
|
||||
|
@ -246,6 +246,7 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
|
||||
|
||||
CodeGenResult AssembleArchInstruction(Instruction* instr);
|
||||
void AssembleArchJump(RpoNumber target);
|
||||
void AssembleArchJumpRegardlessOfAssemblyOrder(RpoNumber target);
|
||||
void AssembleArchBranch(Instruction* instr, BranchInfo* branch);
|
||||
|
||||
// Generates special branch for deoptimization condition.
|
||||
|
@ -3736,8 +3736,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
AssembleArchBranch(instr, branch);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ jmp(GetLabel(target));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
@ -1938,8 +1938,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
AssembleArchBranch(instr, branch);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ Branch(GetLabel(target));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
@ -3689,8 +3689,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
AssembleArchBranch(instr, branch);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ Branch(GetLabel(target));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
@ -3879,8 +3879,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
AssembleArchBranch(instr, branch);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ Branch(GetLabel(target));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
@ -3792,8 +3792,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
AssembleArchBranch(instr, branch);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ b(GetLabel(target));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
@ -3488,8 +3488,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
AssembleArchBranch(instr, branch);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ Branch(GetLabel(target));
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchTrap(Instruction* instr,
|
||||
|
@ -3686,8 +3686,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
AssembleArchBranch(instr, branch);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ b(GetLabel(target));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
@ -4428,8 +4428,9 @@ void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchJump(RpoNumber target) {
|
||||
if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
|
||||
void CodeGenerator::AssembleArchJumpRegardlessOfAssemblyOrder(
|
||||
RpoNumber target) {
|
||||
__ jmp(GetLabel(target));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
|
Loading…
Reference in New Issue
Block a user