Commit 4f62b4bb authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[arm] Port the skipping of arguments adaptor frames.

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

Bug: v8:8895
Doc: http://bit.ly/v8-faster-calls-with-arguments-mismatch
Change-Id: I96a0425d390f041001df0356d4bfd71ad1e98b5a
Reviewed-on: https://chromium-review.googlesource.com/c/1491592Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59918}
parent 0a6ae5b4
...@@ -2308,20 +2308,28 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { ...@@ -2308,20 +2308,28 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -- r3 : new target (passed through to callee) // -- r3 : new target (passed through to callee)
// ----------------------------------- // -----------------------------------
Label invoke, dont_adapt_arguments, stack_overflow; Label dont_adapt_arguments, stack_overflow, skip_adapt_arguments;
Label enough, too_few;
__ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
__ b(eq, &dont_adapt_arguments); __ b(eq, &dont_adapt_arguments);
__ cmp(r0, r2); __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ b(lt, &too_few); __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kFlagsOffset));
__ tst(r4,
Operand(SharedFunctionInfo::IsSafeToSkipArgumentsAdaptorBit::kMask));
__ b(ne, &skip_adapt_arguments);
Register scratch = r5; // -------------------------------------------
// Adapt arguments.
// -------------------------------------------
{
Label under_application, over_application, invoke;
__ cmp(r0, r2);
__ b(lt, &under_application);
{ // Enough parameters: actual >= expected // Enough parameters: actual >= expected
__ bind(&enough); __ bind(&over_application);
{
EnterArgumentsAdaptorFrame(masm); EnterArgumentsAdaptorFrame(masm);
Generate_StackOverflowCheck(masm, r2, scratch, &stack_overflow); Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
// Calculate copy start address into r0 and copy end address into r4. // Calculate copy start address into r0 and copy end address into r4.
// r0: actual number of arguments as a smi // r0: actual number of arguments as a smi
...@@ -2342,8 +2350,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { ...@@ -2342,8 +2350,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
Label copy; Label copy;
__ bind(&copy); __ bind(&copy);
__ ldr(scratch, MemOperand(r0, 0)); __ ldr(r5, MemOperand(r0, 0));
__ push(scratch); __ push(r5);
__ cmp(r0, r4); // Compare before moving to next argument. __ cmp(r0, r4); // Compare before moving to next argument.
__ sub(r0, r0, Operand(kPointerSize)); __ sub(r0, r0, Operand(kPointerSize));
__ b(ne, &copy); __ b(ne, &copy);
...@@ -2351,10 +2359,11 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { ...@@ -2351,10 +2359,11 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ b(&invoke); __ b(&invoke);
} }
{ // Too few parameters: Actual < expected // Too few parameters: Actual < expected
__ bind(&too_few); __ bind(&under_application);
{
EnterArgumentsAdaptorFrame(masm); EnterArgumentsAdaptorFrame(masm);
Generate_StackOverflowCheck(masm, r2, scratch, &stack_overflow); Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
// Calculate copy start address into r0 and copy end address is fp. // Calculate copy start address into r0 and copy end address is fp.
// r0: actual number of arguments as a smi // r0: actual number of arguments as a smi
...@@ -2372,8 +2381,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { ...@@ -2372,8 +2381,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ bind(&copy); __ bind(&copy);
// Adjust load for return address and receiver. // Adjust load for return address and receiver.
__ ldr(scratch, MemOperand(r0, 2 * kPointerSize)); __ ldr(r5, MemOperand(r0, 2 * kPointerSize));
__ push(scratch); __ push(r5);
__ cmp(r0, fp); // Compare before moving to next argument. __ cmp(r0, fp); // Compare before moving to next argument.
__ sub(r0, r0, Operand(kPointerSize)); __ sub(r0, r0, Operand(kPointerSize));
...@@ -2383,7 +2392,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { ...@@ -2383,7 +2392,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// r1: function // r1: function
// r2: expected number of arguments // r2: expected number of arguments
// r3: new target (passed through to callee) // r3: new target (passed through to callee)
__ LoadRoot(scratch, RootIndex::kUndefinedValue); __ LoadRoot(r5, RootIndex::kUndefinedValue);
__ sub(r4, fp, Operand(r2, LSL, kPointerSizeLog2)); __ sub(r4, fp, Operand(r2, LSL, kPointerSizeLog2));
// Adjust for frame. // Adjust for frame.
__ sub(r4, r4, __ sub(r4, r4,
...@@ -2392,7 +2401,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { ...@@ -2392,7 +2401,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
Label fill; Label fill;
__ bind(&fill); __ bind(&fill);
__ push(scratch); __ push(r5);
__ cmp(sp, r4); __ cmp(sp, r4);
__ b(ne, &fill); __ b(ne, &fill);
} }
...@@ -2408,11 +2417,48 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { ...@@ -2408,11 +2417,48 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
__ CallCodeObject(r2); __ CallCodeObject(r2);
// Store offset of return address for deoptimizer. // 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. // Exit frame and return.
LeaveArgumentsAdaptorFrame(masm); LeaveArgumentsAdaptorFrame(masm);
__ Jump(lr); __ Jump(lr);
}
// -------------------------------------------
// 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(r0, r2);
__ b(lt, &under_application);
__ bind(&over_application);
{
// Remove superfluous parameters from the stack.
__ sub(r4, r0, r2);
__ mov(r0, r2);
__ add(sp, sp, Operand(r4, LSL, kPointerSizeLog2));
__ b(&dont_adapt_arguments);
}
__ bind(&under_application);
{
// Fill remaining expected arguments with undefined values.
Label fill;
__ LoadRoot(r4, RootIndex::kUndefinedValue);
__ bind(&fill);
__ add(r0, r0, Operand(1));
__ push(r4);
__ cmp(r0, r2);
__ b(lt, &fill);
__ b(&dont_adapt_arguments);
}
}
// ------------------------------------------- // -------------------------------------------
// 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