Commit ce1639d8 authored by Shiyu Zhang's avatar Shiyu Zhang Committed by Commit Bot

[builtins] Create new builtins to set up args for CPP/API builtins

The CPP builtins execute the same piece of code to prepare context before
jumping into CEntryStub. By creating new ASM builtin to execute that common
piece of code, ~7KB code size (tested on x64) of snapshot_blob.bin can be 
reduced without any negative performance impact.

BUG=

Change-Id: I744369e8723dcd902b61dc50645db66bea884441
Reviewed-on: https://chromium-review.googlesource.com/595119Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47590}
parent f38c92a9
......@@ -21,10 +21,32 @@ namespace internal {
void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
ExitFrameType exit_frame_type) {
#if defined(__thumb__)
// Thumb mode builtin.
DCHECK((reinterpret_cast<intptr_t>(
ExternalReference(address, masm->isolate()).address()) &
1) == 1);
#endif
__ mov(r5, Operand(ExternalReference(address, masm->isolate())));
if (exit_frame_type == BUILTIN_EXIT) {
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithBuiltinExitFrame),
RelocInfo::CODE_TARGET);
} else {
DCHECK(exit_frame_type == EXIT);
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithExitFrame),
RelocInfo::CODE_TARGET);
}
}
namespace {
void AdaptorWithExitFrameType(MacroAssembler* masm,
Builtins::ExitFrameType exit_frame_type) {
// ----------- S t a t e -------------
// -- r0 : number of arguments excluding receiver
// -- r1 : target
// -- r3 : new.target
// -- r5 : entry point
// -- sp[0] : last argument
// -- ...
// -- sp[4 * (argc - 1)] : first argument
......@@ -38,8 +60,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
// ordinary functions).
__ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
// JumpToExternalReference expects r0 to contain the number of arguments
// including the receiver and the extra arguments.
// CEntryStub expects r0 to contain the number of arguments including the
// receiver and the extra arguments.
const int num_extra_args = 3;
__ add(r0, r0, Operand(num_extra_args + 1));
......@@ -48,8 +70,22 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
__ Push(r0, r1, r3);
__ SmiUntag(r0);
__ JumpToExternalReference(ExternalReference(address, masm->isolate()),
exit_frame_type == BUILTIN_EXIT);
// Jump to the C entry runtime stub directly here instead of using
// JumpToExternalReference. We have already loaded entry point to r5
// in Generate_adaptor.
__ mov(r1, r5);
CEntryStub stub(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
exit_frame_type == Builtins::BUILTIN_EXIT);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_AdaptorWithExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, EXIT);
}
void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
// Load the built-in InternalArray function from the current context.
......
......@@ -34,10 +34,26 @@ static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
ExitFrameType exit_frame_type) {
__ Mov(x5, ExternalReference(address, masm->isolate()));
if (exit_frame_type == BUILTIN_EXIT) {
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithBuiltinExitFrame),
RelocInfo::CODE_TARGET);
} else {
DCHECK(exit_frame_type == EXIT);
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithExitFrame),
RelocInfo::CODE_TARGET);
}
}
namespace {
void AdaptorWithExitFrameType(MacroAssembler* masm,
Builtins::ExitFrameType exit_frame_type) {
// ----------- S t a t e -------------
// -- x0 : number of arguments excluding receiver
// -- x1 : target
// -- x3 : new target
// -- x5 : entry point
// -- sp[0] : last argument
// -- ...
// -- sp[4 * (argc - 1)] : first argument
......@@ -51,8 +67,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
// ordinary functions).
__ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
// JumpToExternalReference expects x0 to contain the number of arguments
// including the receiver and the extra arguments.
// CEntryStub expects x0 to contain the number of arguments including the
// receiver and the extra arguments.
const int num_extra_args = 3;
__ Add(x0, x0, num_extra_args + 1);
......@@ -61,8 +77,22 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
__ Push(x0, x1, x3);
__ SmiUntag(x0);
__ JumpToExternalReference(ExternalReference(address, masm->isolate()),
exit_frame_type == BUILTIN_EXIT);
// Jump to the C entry runtime stub directly here instead of using
// JumpToExternalReference. We have already loaded entry point to x5
// in Generate_adaptor.
__ mov(x1, x5);
CEntryStub stub(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
exit_frame_type == Builtins::BUILTIN_EXIT);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_AdaptorWithExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, EXIT);
}
void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
......
......@@ -27,6 +27,10 @@ namespace internal {
/* GC write barrirer */ \
TFC(RecordWrite, RecordWrite, 1) \
\
/* Adaptors for CPP/API builtin */ \
ASM(AdaptorWithExitFrame) \
ASM(AdaptorWithBuiltinExitFrame) \
\
/* Calls */ \
ASM(ArgumentsAdaptorTrampoline) \
/* ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) */ \
......
......@@ -17,8 +17,24 @@ namespace internal {
void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
ExitFrameType exit_frame_type) {
__ mov(ebx, Immediate(ExternalReference(address, masm->isolate())));
if (exit_frame_type == BUILTIN_EXIT) {
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithBuiltinExitFrame),
RelocInfo::CODE_TARGET);
} else {
DCHECK(exit_frame_type == EXIT);
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithExitFrame),
RelocInfo::CODE_TARGET);
}
}
namespace {
void AdaptorWithExitFrameType(MacroAssembler* masm,
Builtins::ExitFrameType exit_frame_type) {
// ----------- S t a t e -------------
// -- eax : number of arguments excluding receiver
// -- ebx : entry point
// -- edi : target
// -- edx : new.target
// -- esp[0] : return address
......@@ -35,8 +51,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
// ordinary functions).
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
// JumpToExternalReference expects eax to contain the number of arguments
// including the receiver and the extra arguments.
// CEntryStub expects eax to contain the number of arguments including the
// receiver and the extra arguments.
const int num_extra_args = 3;
__ add(eax, Immediate(num_extra_args + 1));
......@@ -49,8 +65,20 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
__ Push(edx);
__ PushReturnAddressFrom(ecx);
__ JumpToExternalReference(ExternalReference(address, masm->isolate()),
exit_frame_type == BUILTIN_EXIT);
// Jump to the C entry runtime stub directly here instead of using
// JumpToExternalReference because ebx is loaded by Generate_adaptor.
CEntryStub ces(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
exit_frame_type == Builtins::BUILTIN_EXIT);
__ jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_AdaptorWithExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, EXIT);
}
void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
static void GenerateTailCallToReturnedCode(MacroAssembler* masm,
......
......@@ -18,10 +18,26 @@ namespace internal {
void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
ExitFrameType exit_frame_type) {
__ li(s2, Operand(ExternalReference(address, masm->isolate())));
if (exit_frame_type == BUILTIN_EXIT) {
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithBuiltinExitFrame),
RelocInfo::CODE_TARGET);
} else {
DCHECK(exit_frame_type == EXIT);
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithExitFrame),
RelocInfo::CODE_TARGET);
}
}
namespace {
void AdaptorWithExitFrameType(MacroAssembler* masm,
Builtins::ExitFrameType exit_frame_type) {
// ----------- S t a t e -------------
// -- a0 : number of arguments excluding receiver
// -- a1 : target
// -- a3 : new.target
// -- s2 : entry point
// -- sp[0] : last argument
// -- ...
// -- sp[4 * (argc - 1)] : first argument
......@@ -35,8 +51,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
// ordinary functions).
__ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
// JumpToExternalReference expects a0 to contain the number of arguments
// including the receiver and the extra arguments.
// CEntryStub expects a0 to contain the number of arguments including the
// receiver and the extra arguments.
const int num_extra_args = 3;
__ Addu(a0, a0, num_extra_args + 1);
......@@ -45,8 +61,23 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
__ Push(a0, a1, a3);
__ SmiUntag(a0);
__ JumpToExternalReference(ExternalReference(address, masm->isolate()),
PROTECT, exit_frame_type == BUILTIN_EXIT);
// Jump to the C entry runtime stub directly here instead of using
// JumpToExternalReference. We have already loaded entry point to s2
// in Generate_adaptor.
__ mov(a1, s2);
CEntryStub stub(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
exit_frame_type == Builtins::BUILTIN_EXIT);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET, al, zero_reg,
Operand(zero_reg), PROTECT);
}
} // namespace
void Builtins::Generate_AdaptorWithExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, EXIT);
}
void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
// Load the built-in InternalArray function from the current context.
......
......@@ -18,10 +18,26 @@ namespace internal {
void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
ExitFrameType exit_frame_type) {
__ li(s2, Operand(ExternalReference(address, masm->isolate())));
if (exit_frame_type == BUILTIN_EXIT) {
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithBuiltinExitFrame),
RelocInfo::CODE_TARGET);
} else {
DCHECK(exit_frame_type == EXIT);
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithExitFrame),
RelocInfo::CODE_TARGET);
}
}
namespace {
void AdaptorWithExitFrameType(MacroAssembler* masm,
Builtins::ExitFrameType exit_frame_type) {
// ----------- S t a t e -------------
// -- a0 : number of arguments excluding receiver
// -- a1 : target
// -- a3 : new.target
// -- s2 : entry point
// -- sp[0] : last argument
// -- ...
// -- sp[8 * (argc - 1)] : first argument
......@@ -35,8 +51,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
// ordinary functions).
__ Ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
// JumpToExternalReference expects a0 to contain the number of arguments
// including the receiver and the extra arguments.
// CEntryStub expects a0 to contain the number of arguments including the
// receiver and the extra arguments.
const int num_extra_args = 3;
__ Daddu(a0, a0, num_extra_args + 1);
......@@ -45,8 +61,23 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
__ Push(a0, a1, a3);
__ SmiUntag(a0);
__ JumpToExternalReference(ExternalReference(address, masm->isolate()),
PROTECT, exit_frame_type == BUILTIN_EXIT);
// Jump to the C entry runtime stub directly here instead of using
// JumpToExternalReference. We have already loaded entry point to s2
// in Generate_adaptor.
__ mov(a1, s2);
CEntryStub stub(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
exit_frame_type == Builtins::BUILTIN_EXIT);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET, al, zero_reg,
Operand(zero_reg), PROTECT);
}
} // namespace
void Builtins::Generate_AdaptorWithExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, EXIT);
}
void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
// Load the built-in InternalArray function from the current context.
......
......@@ -18,10 +18,26 @@ namespace internal {
void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
ExitFrameType exit_frame_type) {
__ mov(r15, Operand(ExternalReference(address, masm->isolate())));
if (exit_frame_type == BUILTIN_EXIT) {
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithBuiltinExitFrame),
RelocInfo::CODE_TARGET);
} else {
DCHECK(exit_frame_type == EXIT);
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithExitFrame),
RelocInfo::CODE_TARGET);
}
}
namespace {
void AdaptorWithExitFrameType(MacroAssembler* masm,
Builtins::ExitFrameType exit_frame_type) {
// ----------- S t a t e -------------
// -- r3 : number of arguments excluding receiver
// -- r4 : target
// -- r6 : new.target
// -- r15 : entry point
// -- sp[0] : last argument
// -- ...
// -- sp[4 * (argc - 1)] : first argument
......@@ -35,8 +51,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
// ordinary functions).
__ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
// JumpToExternalReference expects r3 to contain the number of arguments
// including the receiver and the extra arguments.
// CEntryStub expects r3 to contain the number of arguments including the
// receiver and the extra arguments.
const int num_extra_args = 3;
__ addi(r3, r3, Operand(num_extra_args + 1));
......@@ -45,8 +61,22 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
__ Push(r3, r4, r6);
__ SmiUntag(r3);
__ JumpToExternalReference(ExternalReference(address, masm->isolate()),
exit_frame_type == BUILTIN_EXIT);
// Jump to the C entry runtime stub directly here instead of using
// JumpToExternalReference. We have already loaded entry point to r15
// in Generate_adaptor.
__ mr(r4, r15);
CEntryStub stub(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
exit_frame_type == Builtins::BUILTIN_EXIT);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_AdaptorWithExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, EXIT);
}
void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
// Load the built-in InternalArray function from the current context.
......
......@@ -18,10 +18,26 @@ namespace internal {
void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
ExitFrameType exit_frame_type) {
__ mov(r7, Operand(ExternalReference(address, masm->isolate())));
if (exit_frame_type == BUILTIN_EXIT) {
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithBuiltinExitFrame),
RelocInfo::CODE_TARGET);
} else {
DCHECK(exit_frame_type == EXIT);
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithExitFrame),
RelocInfo::CODE_TARGET);
}
}
namespace {
void AdaptorWithExitFrameType(MacroAssembler* masm,
Builtins::ExitFrameType exit_frame_type) {
// ----------- S t a t e -------------
// -- r2 : number of arguments excluding receiver
// -- r3 : target
// -- r5 : new.target
// -- r7 : entry point
// -- sp[0] : last argument
// -- ...
// -- sp[4 * (argc - 1)] : first argument
......@@ -35,8 +51,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
// ordinary functions).
__ LoadP(cp, FieldMemOperand(r3, JSFunction::kContextOffset));
// JumpToExternalReference expects r2 to contain the number of arguments
// including the receiver and the extra arguments.
// CEntryStub expects r2 to contain the number of arguments including the
// receiver and the extra arguments.
const int num_extra_args = 3;
__ AddP(r2, r2, Operand(num_extra_args + 1));
......@@ -45,8 +61,22 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
__ Push(r2, r3, r5);
__ SmiUntag(r2);
__ JumpToExternalReference(ExternalReference(address, masm->isolate()),
exit_frame_type == BUILTIN_EXIT);
// Jump to the C entry runtime stub directly here instead of using
// JumpToExternalReference. We have already loaded entry point to r7
// in Generate_adaptor.
__ LoadRR(r3, r7);
CEntryStub stub(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
exit_frame_type == Builtins::BUILTIN_EXIT);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_AdaptorWithExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, EXIT);
}
void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
// Load the built-in InternalArray function from the current context.
......
......@@ -19,8 +19,24 @@ namespace internal {
void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
ExitFrameType exit_frame_type) {
__ LoadAddress(rbx, ExternalReference(address, masm->isolate()));
if (exit_frame_type == BUILTIN_EXIT) {
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithBuiltinExitFrame),
RelocInfo::CODE_TARGET);
} else {
DCHECK(exit_frame_type == EXIT);
__ Jump(BUILTIN_CODE(masm->isolate(), AdaptorWithExitFrame),
RelocInfo::CODE_TARGET);
}
}
namespace {
void AdaptorWithExitFrameType(MacroAssembler* masm,
Builtins::ExitFrameType exit_frame_type) {
// ----------- S t a t e -------------
// -- rax : number of arguments excluding receiver
// -- rbx : entry point
// -- rdi : target
// -- rdx : new.target
// -- rsp[0] : return address
......@@ -40,8 +56,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
// ordinary functions).
__ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
// JumpToExternalReference expects rax to contain the number of arguments
// including the receiver and the extra arguments.
// CEntryStub expects rax to contain the number of arguments including the
// receiver and the extra arguments.
const int num_extra_args = 3;
__ addp(rax, Immediate(num_extra_args + 1));
......@@ -55,8 +71,20 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
__ Push(rdx);
__ PushReturnAddressFrom(kScratchRegister);
__ JumpToExternalReference(ExternalReference(address, masm->isolate()),
exit_frame_type == BUILTIN_EXIT);
// Jump to the C entry runtime stub directly here instead of using
// JumpToExternalReference because rbx is loaded by Generate_adaptor.
CEntryStub ces(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
exit_frame_type == Builtins::BUILTIN_EXIT);
__ jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_AdaptorWithExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, EXIT);
}
void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
......
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