Commit 421cf613 authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

PPC/s390: [builtins] Improve CallApiCallback calling convention.

Port c142e0a2

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

R=bmeurer@chromium.org, joransiu@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N

Change-Id: Ic6c246bb28a6affa6fe015c1207c773b375a2b30
Reviewed-on: https://chromium-review.googlesource.com/c/1470443Reviewed-by: 's avatarMilad Farazmand <miladfar@ca.ibm.com>
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#59562}
parent c79a63e6
......@@ -3002,32 +3002,23 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- cp : kTargetContext
// -- r4 : kApiFunctionAddress
// -- r5 : kArgc
// --
// -- cp : context
// -- r4 : api function address
// -- r5 : arguments count (not including the receiver)
// -- r6 : call data
// -- r3 : holder
// -- sp[0] : last argument
// -- ...
// -- sp[(argc - 1)* 4] : first argument
// -- sp[(argc + 0) * 4] : receiver
// -- sp[(argc + 1) * 4] : kHolder
// -- sp[(argc + 2) * 4] : kCallData
// -----------------------------------
Register api_function_address = r4;
Register argc = r5;
Register call_data = r6;
Register holder = r3;
Register scratch = r7;
Register index = r8; // For indexing MemOperands.
DCHECK(!AreAliased(api_function_address, argc, scratch, index));
// Stack offsets (without argc).
static constexpr int kReceiverOffset = 0;
static constexpr int kHolderOffset = kReceiverOffset + 1;
static constexpr int kCallDataOffset = kHolderOffset + 1;
// Extra stack arguments are: the receiver, kHolder, kCallData.
static constexpr int kExtraStackArgumentCount = 3;
DCHECK(!AreAliased(api_function_address, argc, call_data, holder, scratch));
typedef FunctionCallbackArguments FCA;
......@@ -3053,26 +3044,22 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
__ subi(sp, sp, Operand(FCA::kArgsLength * kPointerSize));
// kHolder.
__ addi(index, argc, Operand(FCA::kArgsLength + kHolderOffset));
__ ShiftLeftImm(ip, index, Operand(kPointerSizeLog2));
__ LoadPX(scratch, MemOperand(sp, ip));
__ StoreP(scratch, MemOperand(sp, 0 * kPointerSize));
__ StoreP(holder, MemOperand(sp, 0 * kPointerSize));
// kIsolate.
__ Move(scratch, ExternalReference::isolate_address(masm->isolate()));
__ StoreP(scratch, MemOperand(sp, 1 * kPointerSize));
// kReturnValueDefaultValue, kReturnValue, and kNewTarget.
// kReturnValueDefaultValue and kReturnValue.
__ LoadRoot(scratch, RootIndex::kUndefinedValue);
__ StoreP(scratch, MemOperand(sp, 2 * kPointerSize));
__ StoreP(scratch, MemOperand(sp, 3 * kPointerSize));
__ StoreP(scratch, MemOperand(sp, 5 * kPointerSize));
// kData.
__ addi(index, argc, Operand(FCA::kArgsLength + kCallDataOffset));
__ ShiftLeftImm(ip, index, Operand(kPointerSizeLog2));
__ LoadPX(scratch, MemOperand(sp, ip));
__ StoreP(scratch, MemOperand(sp, 4 * kPointerSize));
__ StoreP(call_data, MemOperand(sp, 4 * kPointerSize));
// kNewTarget.
__ StoreP(scratch, MemOperand(sp, 5 * kPointerSize));
// Keep a pointer to kHolder (= implicit_args) in a scratch register.
// We use it below to set up the FunctionCallbackInfo object.
......@@ -3111,7 +3098,7 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
// We also store the number of bytes to drop from the stack after returning
// from the API function here.
__ mov(scratch,
Operand((FCA::kArgsLength + kExtraStackArgumentCount) * kPointerSize));
Operand((FCA::kArgsLength + 1 /* receiver */) * kPointerSize));
__ ShiftLeftImm(ip, argc, Operand(kPointerSizeLog2));
__ add(scratch, scratch, ip);
__ StoreP(scratch,
......
......@@ -3038,32 +3038,23 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- cp : kTargetContext
// -- r3 : kApiFunctionAddress
// -- r4 : kArgc
// --
// -- cp : context
// -- r4 : api function address
// -- r4 : arguments count (not including the receiver)
// -- r5 : call data
// -- r2 : holder
// -- sp[0] : last argument
// -- ...
// -- sp[(argc - 1) * 4] : first argument
// -- sp[(argc + 0) * 4] : receiver
// -- sp[(argc + 1) * 4] : kHolder
// -- sp[(argc + 2) * 4] : kCallData
// -----------------------------------
Register api_function_address = r3;
Register argc = r4;
Register call_data = r5;
Register holder = r2;
Register scratch = r6;
Register index = r7; // For indexing MemOperands.
DCHECK(!AreAliased(api_function_address, argc, scratch, index));
// Stack offsets (without argc).
static constexpr int kReceiverOffset = 0;
static constexpr int kHolderOffset = kReceiverOffset + 1;
static constexpr int kCallDataOffset = kHolderOffset + 1;
// Extra stack arguments are: the receiver, kHolder, kCallData.
static constexpr int kExtraStackArgumentCount = 3;
DCHECK(!AreAliased(api_function_address, argc, call_data, holder, scratch));
typedef FunctionCallbackArguments FCA;
......@@ -3089,26 +3080,22 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
__ lay(sp, MemOperand(sp, -(FCA::kArgsLength * kPointerSize)));
// kHolder.
__ AddP(index, argc, Operand(FCA::kArgsLength + kHolderOffset));
__ ShiftLeftP(r1, index, Operand(kPointerSizeLog2));
__ LoadP(scratch, MemOperand(sp, r1));
__ StoreP(scratch, MemOperand(sp, 0 * kPointerSize));
__ StoreP(holder, MemOperand(sp, 0 * kPointerSize));
// kIsolate.
__ Move(scratch, ExternalReference::isolate_address(masm->isolate()));
__ StoreP(scratch, MemOperand(sp, 1 * kPointerSize));
// kReturnValueDefaultValue, kReturnValue, and kNewTarget.
// kReturnValueDefaultValue and kReturnValue.
__ LoadRoot(scratch, RootIndex::kUndefinedValue);
__ StoreP(scratch, MemOperand(sp, 2 * kPointerSize));
__ StoreP(scratch, MemOperand(sp, 3 * kPointerSize));
__ StoreP(scratch, MemOperand(sp, 5 * kPointerSize));
// kData.
__ AddP(index, argc, Operand(FCA::kArgsLength + kCallDataOffset));
__ ShiftLeftP(r1, index, Operand(kPointerSizeLog2));
__ LoadP(scratch, MemOperand(sp, r1));
__ StoreP(scratch, MemOperand(sp, 4 * kPointerSize));
__ StoreP(call_data, MemOperand(sp, 4 * kPointerSize));
// kNewTarget.
__ StoreP(scratch, MemOperand(sp, 5 * kPointerSize));
// Keep a pointer to kHolder (= implicit_args) in a scratch register.
// We use it below to set up the FunctionCallbackInfo object.
......@@ -3148,7 +3135,7 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) {
// We also store the number of bytes to drop from the stack after returning
// from the API function here.
__ mov(scratch,
Operand((FCA::kArgsLength + kExtraStackArgumentCount) * kPointerSize));
Operand((FCA::kArgsLength + 1 /* receiver */) * kPointerSize));
__ ShiftLeftP(r1, argc, Operand(kPointerSizeLog2));
__ AddP(scratch, r1);
__ StoreP(scratch,
......
......@@ -204,9 +204,10 @@ void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
void ApiCallbackDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
JavaScriptFrame::context_register(), // kTargetContext
r4, // kApiFunctionAddress
r5, // kArgc
r4, // kApiFunctionAddress
r5, // kArgc
r6, // kCallData
r3, // kHolder
};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
......
......@@ -202,9 +202,10 @@ void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
void ApiCallbackDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
JavaScriptFrame::context_register(), // kTargetContext
r3, // kApiFunctionAddress
r4, // kArgc
r3, // kApiFunctionAddress
r4, // kArgc
r5, // kCallData
r2, // kHolder
};
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