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:
Seth Brenith 2021-12-13 10:32:26 -08:00 committed by V8 LUCI CQ
parent dad520133c
commit dd9d4c96c1
12 changed files with 37 additions and 21 deletions

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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