Commit d9b59c7d authored by Yu Yin's avatar Yu Yin Committed by Commit Bot

[mips][builtin] Improve CallApiCallback calling convention.

Port https://crrev.com/c/1469821

Original Commit Message:

    Refactor the CallApiCallback builtin to

    - pass the context as with other stubs, and
    - pass holder and call data in registers.

    This avoids having to place holder and call data onto the stack, and
    thus makes it possible to easily call the CallApiCallback builtin from
    other builtins while just forwarding the (stack) arguments. The idea
    is to use this in the future to optimize the general case of calling
    into any API method via a FunctionTemplateInfo and doing appropriate
    security and/or interface checks upfront as necessary (eventually making
    the HandleApiCall C++ builtin obsolete at some point).

Change-Id: Ice52b68678fbea69e765c22daa3134524860e5de
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1505234Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarPredrag Rudic <prudic@wavecomp.com>
Commit-Queue: Yu Yin <xwafish@gmail.com>
Cr-Commit-Position: refs/heads/master@{#60049}
parent df7eb1d3
...@@ -2943,32 +2943,27 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, ...@@ -2943,32 +2943,27 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
void Builtins::Generate_CallApiCallback(MacroAssembler* masm) { void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- cp : kTargetContext // -- cp : context
// -- a1 : kApiFunctionAddress // -- a1 : api function address
// -- a2 : kArgc // -- a2 : arguments count (not including the receiver)
// -- a3 : call data
// -- a0 : holder
// -- // --
// -- sp[0] : last argument // -- sp[0] : last argument
// -- ... // -- ...
// -- sp[(argc - 1) * 4] : first argument // -- sp[(argc - 1) * 4] : first argument
// -- sp[(argc + 0) * 4] : receiver // -- sp[(argc + 0) * 4] : receiver
// -- sp[(argc + 1) * 4] : kHolder
// -- sp[(argc + 2) * 4] : kCallData
// ----------------------------------- // -----------------------------------
Register api_function_address = a1; Register api_function_address = a1;
Register argc = a2; Register argc = a2;
Register call_data = a3;
Register holder = a0;
Register scratch = t0; Register scratch = t0;
Register base = t1; // For addressing MemOperands on the stack. Register base = t1; // For addressing MemOperands on the stack.
DCHECK(!AreAliased(api_function_address, argc, scratch, base)); DCHECK(!AreAliased(api_function_address, argc, call_data,
holder, scratch, base));
// Stack offsets (without argc).
static constexpr int kReceiverOffset = 0 * kPointerSize;
static constexpr int kHolderOffset = kReceiverOffset + kPointerSize;
static constexpr int kCallDataOffset = kHolderOffset + kPointerSize;
// Extra stack arguments are: the receiver, kHolder, kCallData.
static constexpr int kExtraStackArgumentCount = 3;
typedef FunctionCallbackArguments FCA; typedef FunctionCallbackArguments FCA;
...@@ -2998,22 +2993,22 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) { ...@@ -2998,22 +2993,22 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
__ Subu(sp, sp, Operand(FCA::kArgsLength * kPointerSize)); __ Subu(sp, sp, Operand(FCA::kArgsLength * kPointerSize));
// kHolder. // kHolder.
__ lw(scratch, MemOperand(base, kHolderOffset)); __ sw(holder, MemOperand(sp, 0 * kPointerSize));
__ sw(scratch, MemOperand(sp, 0 * kPointerSize));
// kIsolate. // kIsolate.
__ li(scratch, ExternalReference::isolate_address(masm->isolate())); __ li(scratch, ExternalReference::isolate_address(masm->isolate()));
__ sw(scratch, MemOperand(sp, 1 * kPointerSize)); __ sw(scratch, MemOperand(sp, 1 * kPointerSize));
// kReturnValueDefaultValue, kReturnValue, and kNewTarget. // kReturnValueDefaultValue and kReturnValue.
__ LoadRoot(scratch, RootIndex::kUndefinedValue); __ LoadRoot(scratch, RootIndex::kUndefinedValue);
__ sw(scratch, MemOperand(sp, 2 * kPointerSize)); __ sw(scratch, MemOperand(sp, 2 * kPointerSize));
__ sw(scratch, MemOperand(sp, 3 * kPointerSize)); __ sw(scratch, MemOperand(sp, 3 * kPointerSize));
__ sw(scratch, MemOperand(sp, 5 * kPointerSize));
// kData. // kData.
__ lw(scratch, MemOperand(base, kCallDataOffset)); __ sw(call_data, MemOperand(sp, 4 * kPointerSize));
__ sw(scratch, MemOperand(sp, 4 * kPointerSize));
// kNewTarget.
__ sw(scratch, MemOperand(sp, 5 * kPointerSize));
// Keep a pointer to kHolder (= implicit_args) in a scratch register. // Keep a pointer to kHolder (= implicit_args) in a scratch register.
// We use it below to set up the FunctionCallbackInfo object. // We use it below to set up the FunctionCallbackInfo object.
...@@ -3042,7 +3037,7 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) { ...@@ -3042,7 +3037,7 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
// from the API function here. // from the API function here.
// Note: Unlike on other architectures, this stores the number of slots to // Note: Unlike on other architectures, this stores the number of slots to
// drop, not the number of bytes. // drop, not the number of bytes.
__ Addu(scratch, argc, Operand(FCA::kArgsLength + kExtraStackArgumentCount)); __ Addu(scratch, argc, Operand(FCA::kArgsLength + 1 /* receiver */));
__ sw(scratch, MemOperand(sp, 4 * kPointerSize)); __ sw(scratch, MemOperand(sp, 4 * kPointerSize));
// v8::InvocationCallback's argument. // v8::InvocationCallback's argument.
......
...@@ -2979,32 +2979,27 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, ...@@ -2979,32 +2979,27 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
void Builtins::Generate_CallApiCallback(MacroAssembler* masm) { void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- cp : kTargetContext // -- cp : context
// -- a1 : kApiFunctionAddress // -- a1 : api function address
// -- a2 : kArgc // -- a2 : arguments count (not including the receiver)
// -- a3 : call data
// -- a0 : holder
// -- // --
// -- sp[0] : last argument // -- sp[0] : last argument
// -- ... // -- ...
// -- sp[(argc - 1) * 8] : first argument // -- sp[(argc - 1) * 8] : first argument
// -- sp[(argc + 0) * 8] : receiver // -- sp[(argc + 0) * 8] : receiver
// -- sp[(argc + 1) * 8] : kHolder
// -- sp[(argc + 2) * 8] : kCallData
// ----------------------------------- // -----------------------------------
Register api_function_address = a1; Register api_function_address = a1;
Register argc = a2; Register argc = a2;
Register call_data = a3;
Register holder = a0;
Register scratch = t0; Register scratch = t0;
Register base = t1; // For addressing MemOperands on the stack. Register base = t1; // For addressing MemOperands on the stack.
DCHECK(!AreAliased(api_function_address, argc, scratch, base)); DCHECK(!AreAliased(api_function_address, argc, call_data,
holder, scratch, base));
// Stack offsets (without argc).
static constexpr int kReceiverOffset = 0 * kPointerSize;
static constexpr int kHolderOffset = kReceiverOffset + kPointerSize;
static constexpr int kCallDataOffset = kHolderOffset + kPointerSize;
// Extra stack arguments are: the receiver, kHolder, kCallData.
static constexpr int kExtraStackArgumentCount = 3;
typedef FunctionCallbackArguments FCA; typedef FunctionCallbackArguments FCA;
...@@ -3034,22 +3029,22 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) { ...@@ -3034,22 +3029,22 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
__ Dsubu(sp, sp, Operand(FCA::kArgsLength * kPointerSize)); __ Dsubu(sp, sp, Operand(FCA::kArgsLength * kPointerSize));
// kHolder. // kHolder.
__ Ld(scratch, MemOperand(base, kHolderOffset)); __ Sd(holder, MemOperand(sp, 0 * kPointerSize));
__ Sd(scratch, MemOperand(sp, 0 * kPointerSize));
// kIsolate. // kIsolate.
__ li(scratch, ExternalReference::isolate_address(masm->isolate())); __ li(scratch, ExternalReference::isolate_address(masm->isolate()));
__ Sd(scratch, MemOperand(sp, 1 * kPointerSize)); __ Sd(scratch, MemOperand(sp, 1 * kPointerSize));
// kReturnValueDefaultValue, kReturnValue, and kNewTarget. // kReturnValueDefaultValue and kReturnValue.
__ LoadRoot(scratch, RootIndex::kUndefinedValue); __ LoadRoot(scratch, RootIndex::kUndefinedValue);
__ Sd(scratch, MemOperand(sp, 2 * kPointerSize)); __ Sd(scratch, MemOperand(sp, 2 * kPointerSize));
__ Sd(scratch, MemOperand(sp, 3 * kPointerSize)); __ Sd(scratch, MemOperand(sp, 3 * kPointerSize));
__ Sd(scratch, MemOperand(sp, 5 * kPointerSize));
// kData. // kData.
__ Ld(scratch, MemOperand(base, kCallDataOffset)); __ Sd(call_data, MemOperand(sp, 4 * kPointerSize));
__ Sd(scratch, MemOperand(sp, 4 * kPointerSize));
// kNewTarget.
__ Sd(scratch, MemOperand(sp, 5 * kPointerSize));
// Keep a pointer to kHolder (= implicit_args) in a scratch register. // Keep a pointer to kHolder (= implicit_args) in a scratch register.
// We use it below to set up the FunctionCallbackInfo object. // We use it below to set up the FunctionCallbackInfo object.
...@@ -3082,7 +3077,7 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) { ...@@ -3082,7 +3077,7 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
// from the API function here. // from the API function here.
// Note: Unlike on other architectures, this stores the number of slots to // Note: Unlike on other architectures, this stores the number of slots to
// drop, not the number of bytes. // drop, not the number of bytes.
__ Daddu(scratch, argc, Operand(FCA::kArgsLength + kExtraStackArgumentCount)); __ Daddu(scratch, argc, Operand(FCA::kArgsLength + 1 /* receiver */));
__ Sd(scratch, MemOperand(sp, 4 * kPointerSize)); __ Sd(scratch, MemOperand(sp, 4 * kPointerSize));
// v8::InvocationCallback's argument. // v8::InvocationCallback's argument.
......
...@@ -239,9 +239,10 @@ void ArgumentsAdaptorDescriptor::InitializePlatformSpecific( ...@@ -239,9 +239,10 @@ void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
void ApiCallbackDescriptor::InitializePlatformSpecific( void ApiCallbackDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
JavaScriptFrame::context_register(), // kTargetContext
a1, // kApiFunctionAddress a1, // kApiFunctionAddress
a2, // kArgc a2, // kArgc
a3, // kCallData
a0, // kHolder
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
...@@ -239,9 +239,10 @@ void ArgumentsAdaptorDescriptor::InitializePlatformSpecific( ...@@ -239,9 +239,10 @@ void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
void ApiCallbackDescriptor::InitializePlatformSpecific( void ApiCallbackDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
JavaScriptFrame::context_register(), // kTargetContext
a1, // kApiFunctionAddress a1, // kApiFunctionAddress
a2, // kArgc a2, // kArgc
a3, // kCallData
a0, // kHolder
}; };
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
......
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