[x64] Micro-optimize TailCallBuiltin with condition

Use jcc where possible if using TailCallBuiltin with a condition (e.g.
in the BailoutIfDeoptimized call).

Change-Id: I160096919082b6535550c0e2053522a703c0c264
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3963994
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83823}
This commit is contained in:
Leszek Swirski 2022-10-20 15:35:07 +02:00 committed by V8 LUCI CQ
parent 7cdad3f9c5
commit 8918a05117
4 changed files with 51 additions and 4 deletions

View File

@ -1018,6 +1018,16 @@ void Assembler::near_jmp(intptr_t disp, RelocInfo::Mode rmode) {
emitl(static_cast<int32_t>(disp));
}
void Assembler::near_j(Condition cc, intptr_t disp, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this);
// 0000 1111 1000 tttn #32-bit disp.
emit(0x0F);
emit(0x80 | cc);
DCHECK(is_int32(disp));
if (!RelocInfo::IsNoInfo(rmode)) RecordRelocInfo(rmode);
emitl(static_cast<int32_t>(disp));
}
void Assembler::call(Register adr) {
EnsureSpace ensure_space(this);
// Opcode: FF /2 r64.

View File

@ -821,6 +821,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
static constexpr int kNearJmpInstrSize = 5;
void near_call(intptr_t disp, RelocInfo::Mode rmode);
void near_jmp(intptr_t disp, RelocInfo::Mode rmode);
void near_j(Condition cc, intptr_t disp, RelocInfo::Mode rmode);
void call(Handle<CodeT> target,
RelocInfo::Mode rmode = RelocInfo::CODE_TARGET);

View File

@ -2094,11 +2094,26 @@ void TurboAssembler::Jump(const ExternalReference& reference) {
void TurboAssembler::Jump(Operand op) { jmp(op); }
void TurboAssembler::Jump(Operand op, Condition cc) {
Label skip;
j(NegateCondition(cc), &skip, Label::kNear);
Jump(op);
bind(&skip);
}
void TurboAssembler::Jump(Address destination, RelocInfo::Mode rmode) {
Move(kScratchRegister, destination, rmode);
jmp(kScratchRegister);
}
void TurboAssembler::Jump(Address destination, RelocInfo::Mode rmode,
Condition cc) {
Label skip;
j(NegateCondition(cc), &skip, Label::kNear);
Jump(destination, rmode);
bind(&skip);
}
void TurboAssembler::Jump(Handle<CodeT> code_object, RelocInfo::Mode rmode) {
DCHECK_IMPLIES(options().isolate_independent_code,
Builtins::IsIsolateIndependentBuiltin(*code_object));
@ -2117,10 +2132,7 @@ void TurboAssembler::Jump(Handle<CodeT> code_object, RelocInfo::Mode rmode,
Builtins::IsIsolateIndependentBuiltin(*code_object));
Builtin builtin = Builtin::kNoBuiltinId;
if (isolate()->builtins()->IsBuiltinHandle(code_object, &builtin)) {
Label skip;
j(NegateCondition(cc), &skip, Label::kNear);
TailCallBuiltin(builtin);
bind(&skip);
TailCallBuiltin(builtin, cc);
return;
}
DCHECK(RelocInfo::IsCodeTarget(rmode));
@ -2230,6 +2242,27 @@ void TurboAssembler::TailCallBuiltin(Builtin builtin) {
}
}
void TurboAssembler::TailCallBuiltin(Builtin builtin, Condition cc) {
ASM_CODE_COMMENT_STRING(this,
CommentForOffHeapTrampoline("tail call", builtin));
switch (options().builtin_call_jump_mode) {
case BuiltinCallJumpMode::kAbsolute:
Jump(BuiltinEntry(builtin), RelocInfo::OFF_HEAP_TARGET, cc);
break;
case BuiltinCallJumpMode::kPCRelative:
near_j(cc, static_cast<intptr_t>(builtin), RelocInfo::NEAR_BUILTIN_ENTRY);
break;
case BuiltinCallJumpMode::kIndirect:
Jump(EntryFromBuiltinAsOperand(builtin), cc);
break;
case BuiltinCallJumpMode::kForMksnapshot: {
Handle<CodeT> code = isolate()->builtins()->code_handle(builtin);
j(cc, code, RelocInfo::CODE_TARGET);
break;
}
}
}
void TurboAssembler::LoadCodeObjectEntry(Register destination,
Register code_object) {
ASM_CODE_COMMENT(this);

View File

@ -390,6 +390,7 @@ class V8_EXPORT_PRIVATE TurboAssembler
void CallBuiltinByIndex(Register builtin_index);
void CallBuiltin(Builtin builtin);
void TailCallBuiltin(Builtin builtin);
void TailCallBuiltin(Builtin builtin, Condition cc);
void LoadCodeObjectEntry(Register destination, Register code_object);
void CallCodeObject(Register code_object);
@ -418,8 +419,10 @@ class V8_EXPORT_PRIVATE TurboAssembler
void CodeDataContainerFromCodeT(Register destination, Register codet);
void Jump(Address destination, RelocInfo::Mode rmode);
void Jump(Address destination, RelocInfo::Mode rmode, Condition cc);
void Jump(const ExternalReference& reference);
void Jump(Operand op);
void Jump(Operand op, Condition cc);
void Jump(Handle<CodeT> code_object, RelocInfo::Mode rmode);
void Jump(Handle<CodeT> code_object, RelocInfo::Mode rmode, Condition cc);