[builtins] Streamline API calls

This CL simplifies the API calls by removing some instructions from
the most common path.

Bug: v8:11880
Change-Id: Id8a62c35af51947ad2c152e093346d03c8e2f508
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3855039
Auto-Submit: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82718}
This commit is contained in:
ishell@chromium.org 2022-08-25 10:58:34 +02:00 committed by V8 LUCI CQ
parent ae9d62ea88
commit 1e5c03c78e
4 changed files with 72 additions and 76 deletions

View File

@ -2913,27 +2913,6 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
DCHECK(function_address == r1 || function_address == r2);
Label profiler_enabled, end_profiler_check;
__ Move(r9, ExternalReference::is_profiling_address(isolate));
__ ldrb(r9, MemOperand(r9, 0));
__ cmp(r9, Operand(0));
__ b(ne, &profiler_enabled);
__ Move(r9, ExternalReference::address_of_runtime_stats_flag());
__ ldr(r9, MemOperand(r9, 0));
__ cmp(r9, Operand(0));
__ b(ne, &profiler_enabled);
{
// Call the api function directly.
__ Move(r3, function_address);
__ b(&end_profiler_check);
}
__ bind(&profiler_enabled);
{
// Additional parameter is the address of the actual callback.
__ Move(r3, thunk_ref);
}
__ bind(&end_profiler_check);
// Allocate HandleScope in callee-save registers.
__ Move(r9, next_address);
__ ldr(r4, MemOperand(r9, kNextOffset));
@ -2942,7 +2921,21 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
__ add(r6, r6, Operand(1));
__ str(r6, MemOperand(r9, kLevelOffset));
__ StoreReturnAddressAndCall(r3);
Label profiler_enabled, done_api_call;
__ Move(r8, ExternalReference::is_profiling_address(isolate));
__ ldrb(r8, MemOperand(r8, 0));
__ cmp(r8, Operand(0));
__ b(ne, &profiler_enabled);
#ifdef V8_RUNTIME_CALL_STATS
__ Move(r8, ExternalReference::address_of_runtime_stats_flag());
__ ldr(r8, MemOperand(r8, 0));
__ cmp(r8, Operand(0));
__ b(ne, &profiler_enabled);
#endif // V8_RUNTIME_CALL_STATS
// Call the api function directly.
__ StoreReturnAddressAndCall(function_address);
__ bind(&done_api_call);
Label promote_scheduled_exception;
Label delete_allocated_handles;
@ -2987,6 +2980,14 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
__ mov(pc, lr);
// Call the api function via thunk wrapper.
__ bind(&profiler_enabled);
// Additional parameter is the address of the actual callback.
__ Move(r3, function_address);
__ Move(r8, thunk_ref);
__ StoreReturnAddressAndCall(r8);
__ b(&done_api_call);
// Re-throw by promoting a scheduled exception.
__ bind(&promote_scheduled_exception);
__ TailCallRuntime(Runtime::kPromoteScheduledException);

View File

@ -3349,25 +3349,6 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
DCHECK(function_address == x1 || function_address == x2);
Label profiler_enabled, end_profiler_check;
__ Mov(x10, ExternalReference::is_profiling_address(isolate));
__ Ldrb(w10, MemOperand(x10));
__ Cbnz(w10, &profiler_enabled);
__ Mov(x10, ExternalReference::address_of_runtime_stats_flag());
__ Ldrsw(w10, MemOperand(x10));
__ Cbnz(w10, &profiler_enabled);
{
// Call the api function directly.
__ Mov(x3, function_address);
__ B(&end_profiler_check);
}
__ Bind(&profiler_enabled);
{
// Additional parameter is the address of the actual callback.
__ Mov(x3, thunk_ref);
}
__ Bind(&end_profiler_check);
// Save the callee-save registers we are going to use.
// TODO(all): Is this necessary? ARM doesn't do it.
static_assert(kCallApiFunctionSpillSpace == 4);
@ -3391,8 +3372,20 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
__ Add(level_reg, level_reg, 1);
__ Str(level_reg, MemOperand(handle_scope_base, kLevelOffset));
__ Mov(x10, x3); // TODO(arm64): Load target into x10 directly.
Label profiler_enabled, done_api_call;
__ Mov(x10, ExternalReference::is_profiling_address(isolate));
__ Ldrb(w10, MemOperand(x10));
__ Cbnz(w10, &profiler_enabled);
#ifdef V8_RUNTIME_CALL_STATS
__ Mov(x10, ExternalReference::address_of_runtime_stats_flag());
__ Ldrsw(w10, MemOperand(x10));
__ Cbnz(w10, &profiler_enabled);
#endif // V8_RUNTIME_CALL_STATS
// Call the api function directly.
__ Mov(x10, function_address);
__ StoreReturnAddressAndCall(x10);
__ Bind(&done_api_call);
Label promote_scheduled_exception;
Label delete_allocated_handles;
@ -3447,6 +3440,14 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
__ Ret();
// Call the api function via thunk wrapper.
__ Bind(&profiler_enabled);
// Additional parameter is the address of the actual callback.
__ Mov(x3, function_address);
__ Mov(x10, thunk_ref);
__ StoreReturnAddressAndCall(x10);
__ B(&done_api_call);
// Re-throw by promoting a scheduled exception.
__ Bind(&promote_scheduled_exception);
__ TailCallRuntime(Runtime::kPromoteScheduledException);

View File

@ -3160,30 +3160,20 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
__ mov(esi, __ ExternalReferenceAsOperand(next_address, esi));
__ mov(edi, __ ExternalReferenceAsOperand(limit_address, edi));
Label profiler_enabled, end_profiler_check;
Label profiler_enabled, done_api_call;
__ Move(eax, Immediate(ExternalReference::is_profiling_address(isolate)));
__ cmpb(Operand(eax, 0), Immediate(0));
__ j(not_zero, &profiler_enabled);
#ifdef V8_RUNTIME_CALL_STATS
__ Move(eax, Immediate(ExternalReference::address_of_runtime_stats_flag()));
__ cmp(Operand(eax, 0), Immediate(0));
__ j(not_zero, &profiler_enabled);
{
// Call the api function directly.
__ mov(eax, function_address);
__ jmp(&end_profiler_check);
}
__ bind(&profiler_enabled);
{
// Additional parameter is the address of the actual getter function.
__ mov(thunk_last_arg, function_address);
__ Move(eax, Immediate(thunk_ref));
}
__ bind(&end_profiler_check);
#endif // V8_RUNTIME_CALL_STATS
// Call the api function.
__ call(eax);
// Call the api function directly.
__ call(function_address);
__ bind(&done_api_call);
Label prologue;
// Load the value from ReturnValue
__ mov(eax, return_value_operand);
@ -3191,7 +3181,6 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
Label delete_allocated_handles;
Label leave_exit_frame;
__ bind(&prologue);
// No more valid handles (the result handle was the last one). Restore
// previous handle scope.
__ mov(__ ExternalReferenceAsOperand(next_address, ecx), esi);
@ -3263,6 +3252,14 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
__ jmp(ecx);
}
// Call the api function via thunk wrapper.
__ bind(&profiler_enabled);
// Additional parameter is the address of the actual getter function.
__ mov(thunk_last_arg, function_address);
__ Move(eax, Immediate(thunk_ref));
__ call(eax);
__ jmp(&done_api_call);
// Re-throw by promoting a scheduled exception.
__ bind(&promote_scheduled_exception);
__ TailCallRuntime(Runtime::kPromoteScheduledException);

View File

@ -4415,7 +4415,6 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
Register thunk_last_arg, int stack_space,
Operand* stack_space_operand,
Operand return_value_operand) {
Label prologue;
Label promote_scheduled_exception;
Label delete_allocated_handles;
Label leave_exit_frame;
@ -4442,32 +4441,22 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
__ movq(prev_limit_reg, Operand(base_reg, kLimitOffset));
__ addl(Operand(base_reg, kLevelOffset), Immediate(1));
Label profiler_enabled, end_profiler_check;
Label profiler_enabled, done_api_call;
__ Move(rax, ExternalReference::is_profiling_address(isolate));
__ cmpb(Operand(rax, 0), Immediate(0));
__ j(not_zero, &profiler_enabled);
#ifdef V8_RUNTIME_CALL_STATS
__ Move(rax, ExternalReference::address_of_runtime_stats_flag());
__ cmpl(Operand(rax, 0), Immediate(0));
__ j(not_zero, &profiler_enabled);
{
// Call the api function directly.
__ Move(rax, function_address);
__ jmp(&end_profiler_check);
}
__ bind(&profiler_enabled);
{
// Third parameter is the address of the actual getter function.
__ Move(thunk_last_arg, function_address);
__ Move(rax, thunk_ref);
}
__ bind(&end_profiler_check);
#endif // V8_RUNTIME_CALL_STATS
// Call the api function!
__ call(rax);
// Call the api function directly.
__ call(function_address);
__ bind(&done_api_call);
// Load the value from ReturnValue
__ movq(rax, return_value_operand);
__ bind(&prologue);
// No more valid handles (the result handle was the last one). Restore
// previous handle scope.
@ -4540,6 +4529,14 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
__ ret(0);
}
// Call the api function via thunk wrapper.
__ bind(&profiler_enabled);
// Third parameter is the address of the actual getter function.
__ Move(thunk_last_arg, function_address);
__ Move(rax, thunk_ref);
__ call(rax);
__ jmp(&done_api_call);
// Re-throw by promoting a scheduled exception.
__ bind(&promote_scheduled_exception);
__ TailCallRuntime(Runtime::kPromoteScheduledException);