Commit d71374b1 authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

PPC/s390: [arm] Port the skipping of arguments adaptor frames.

Port 4f62b4bb

Original Commit Message:

    This is a port of the improvements to the ArgumentsAdaptorTrampoline
    that previously landed for x64. It skips the arguments adaptor frame
    creation if the callee cannot observe the actual arguments (as indicated
    by the "is_safe_to_skip_arguments_adaptor" bit on the SharedFunctionInfo),
    and instead just massages the current stack frame appropriately (either
    by pushing more undefineds in case of under application, or by removing
    the superfluous arguments in case of over application).

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

Change-Id: I94824c4b3d94f7c93c7526c865b82649426cd3a4
Reviewed-on: https://chromium-review.googlesource.com/c/1495014Reviewed-by: 's avatarMilad Farazmand <miladfar@ca.ibm.com>
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#59974}
parent c8d0dae8
......@@ -2374,16 +2374,26 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -- r6 : new target (passed through to callee)
// -----------------------------------
Label invoke, dont_adapt_arguments, stack_overflow;
Label enough, too_few;
Label dont_adapt_arguments, stack_overflow, skip_adapt_arguments;
__ cmpli(r5, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
__ beq(&dont_adapt_arguments);
__ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kFlagsOffset));
__ TestBitMask(r7, SharedFunctionInfo::IsSafeToSkipArgumentsAdaptorBit::kMask,
r0);
__ bne(&skip_adapt_arguments, cr0);
// -------------------------------------------
// Adapt arguments.
// -------------------------------------------
{
Label under_application, over_application, invoke;
__ cmp(r3, r5);
__ blt(&too_few);
__ blt(&under_application);
{ // Enough parameters: actual >= expected
__ bind(&enough);
// Enough parameters: actual >= expected
__ bind(&over_application);
{
EnterArgumentsAdaptorFrame(masm);
Generate_StackOverflowCheck(masm, r5, r8, &stack_overflow);
......@@ -2417,9 +2427,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ b(&invoke);
}
{ // Too few parameters: Actual < expected
__ bind(&too_few);
// Too few parameters: Actual < expected
__ bind(&under_application);
{
EnterArgumentsAdaptorFrame(masm);
Generate_StackOverflowCheck(masm, r5, r8, &stack_overflow);
......@@ -2475,11 +2485,49 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ CallCodeObject(r5);
// Store offset of return address for deoptimizer.
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(
masm->pc_offset());
// Exit frame and return.
LeaveArgumentsAdaptorFrame(masm);
__ blr();
}
// -------------------------------------------
// Skip adapt arguments.
// -------------------------------------------
__ bind(&skip_adapt_arguments);
{
// The callee cannot observe the actual arguments, so it's safe to just
// pass the expected arguments by massaging the stack appropriately. See
// http://bit.ly/v8-faster-calls-with-arguments-mismatch for details.
Label under_application, over_application;
__ cmp(r3, r5);
__ blt(&under_application);
__ bind(&over_application);
{
// Remove superfluous parameters from the stack.
__ sub(r7, r3, r5);
__ mr(r3, r5);
__ ShiftLeftImm(r7, r7, Operand(kPointerSizeLog2));
__ add(sp, sp, r7);
__ b(&dont_adapt_arguments);
}
__ bind(&under_application);
{
// Fill remaining expected arguments with undefined values.
Label fill;
__ LoadRoot(r7, RootIndex::kUndefinedValue);
__ bind(&fill);
__ addi(r3, r3, Operand(1));
__ push(r7);
__ cmp(r3, r5);
__ blt(&fill);
__ b(&dont_adapt_arguments);
}
}
// -------------------------------------------
// Dont adapt arguments.
......
......@@ -2428,16 +2428,26 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -- r5 : new target (passed through to callee)
// -----------------------------------
Label invoke, dont_adapt_arguments, stack_overflow;
Label enough, too_few;
Label dont_adapt_arguments, stack_overflow, skip_adapt_arguments;
__ tmll(r4, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
__ b(Condition(1), &dont_adapt_arguments);
__ CmpLogicalP(r2, r4);
__ blt(&too_few);
__ LoadP(r6, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r6, FieldMemOperand(r6, SharedFunctionInfo::kFlagsOffset));
__ tmll(r6,
Operand(SharedFunctionInfo::IsSafeToSkipArgumentsAdaptorBit::kMask));
__ bne(&skip_adapt_arguments);
// -------------------------------------------
// Adapt arguments.
// -------------------------------------------
{
Label under_application, over_application, invoke;
__ CmpP(r2, r4);
__ blt(&under_application);
{ // Enough parameters: actual >= expected
__ bind(&enough);
// Enough parameters: actual >= expected
__ bind(&over_application);
{
EnterArgumentsAdaptorFrame(masm);
Generate_StackOverflowCheck(masm, r4, r7, &stack_overflow);
......@@ -2471,9 +2481,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ b(&invoke);
}
{ // Too few parameters: Actual < expected
__ bind(&too_few);
// Too few parameters: Actual < expected
__ bind(&under_application);
{
EnterArgumentsAdaptorFrame(masm);
Generate_StackOverflowCheck(masm, r4, r7, &stack_overflow);
......@@ -2528,11 +2538,49 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ CallCodeObject(r4);
// Store offset of return address for deoptimizer.
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(
masm->pc_offset());
// Exit frame and return.
LeaveArgumentsAdaptorFrame(masm);
__ Ret();
}
// -------------------------------------------
// Skip adapt arguments.
// -------------------------------------------
__ bind(&skip_adapt_arguments);
{
// The callee cannot observe the actual arguments, so it's safe to just
// pass the expected arguments by massaging the stack appropriately. See
// http://bit.ly/v8-faster-calls-with-arguments-mismatch for details.
Label under_application, over_application;
__ CmpP(r2, r4);
__ blt(&under_application);
__ bind(&over_application);
{
// Remove superfluous parameters from the stack.
__ SubP(r6, r2, r4);
__ lgr(r2, r4);
__ ShiftLeftP(r6, r6, Operand(kPointerSizeLog2));
__ lay(sp, MemOperand(sp, r6));
__ b(&dont_adapt_arguments);
}
__ bind(&under_application);
{
// Fill remaining expected arguments with undefined values.
Label fill;
__ LoadRoot(r6, RootIndex::kUndefinedValue);
__ bind(&fill);
__ AddP(r2, r2, Operand(1));
__ push(r6);
__ CmpP(r2, r4);
__ blt(&fill);
__ b(&dont_adapt_arguments);
}
}
// -------------------------------------------
// Dont adapt arguments.
......
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