Commit b8695906 authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[asm] Don't read the construct_stub field in PushArgsThenConstruct

For mode = kArrayFunction, we know that we need to call the array
constructor stub, so we don't need to read it out from the construct_stub
field. We also don't need to set it in the construct_stub field anymore,
so just use the builtins constructor stub like other builtins.

Also cleans up PushArgsThenCall by adding a dcheck that we are never in
mode = kArrayFunction, so we don't even try to generate code for this
case, but fail earlier instead.

We don't need to load the array function in ArrayConstructor because this
is set up for us by the builtins construct stub. We do have to check if
new_target is actually set before overwriting it with target, as we are
handling both call and construct cases in ArrayConstructor now.

Bug: v8:7503
Change-Id: I3622bf6127eebed8b55c9c199fa938a8e03b8baa
Reviewed-on: https://chromium-review.googlesource.com/973364
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52152}
parent 839f55f5
......@@ -1638,9 +1638,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
// Cache the array maps, needed by ArrayConstructorStub
CacheInitialJSArrayMaps(native_context(), initial_map);
ArrayConstructorStub array_constructor_stub(isolate);
Handle<Code> code = array_constructor_stub.GetCode();
array_function->shared()->SetConstructStub(*code);
array_function->shared()->SetConstructStub(
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
// Set up %ArrayPrototype%.
// The %ArrayPrototype% has TERMINAL_FAST_ELEMENTS_KIND in order to ensure
......
......@@ -88,12 +88,6 @@ void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
// Load the built-in Array function from the current context.
static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
// Load the Array function from the current native context.
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, result);
}
void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : number of arguments
......@@ -122,27 +116,30 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : number of arguments
// -- r1 : array function
// -- lr : return address
// -- sp[...]: constructor arguments
// -----------------------------------
Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
// Get the Array function.
GenerateLoadArrayFunction(masm, r1);
if (FLAG_debug_code) {
// Initial map for the builtin Array functions should be maps.
__ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
__ SmiTst(r2);
__ ldr(r7, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
__ SmiTst(r7);
__ Assert(ne, AbortReason::kUnexpectedInitialMapForArrayFunction);
__ CompareObjectType(r2, r3, r4, MAP_TYPE);
__ CompareObjectType(r7, r8, r9, MAP_TYPE);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
__ mov(r3, r1);
// r2 is the AllocationSite - here undefined.
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
// If r3 (new target) is undefined, then this is the 'Call' case, so move
// r1 (the constructor) to r3.
__ cmp(r3, r2);
__ mov(r3, r1, LeaveCC, eq);
// Run the native code for the Array function called as a normal function.
// tail call a stub
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
}
......@@ -1070,6 +1067,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
InterpreterPushArgsMode mode) {
DCHECK(mode != InterpreterPushArgsMode::kArrayFunction);
// ----------- S t a t e -------------
// -- r0 : the number of arguments (not including the receiver)
// -- r2 : the address of the first argument to be pushed. Subsequent
......@@ -1098,10 +1096,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
}
// Call the target.
if (mode == InterpreterPushArgsMode::kArrayFunction) {
// Unreachable code.
__ bkpt(0);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
__ Jump(BUILTIN_CODE(masm->isolate(), CallWithSpread),
RelocInfo::CODE_TARGET);
} else {
......@@ -1148,12 +1143,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
if (mode == InterpreterPushArgsMode::kArrayFunction) {
__ AssertFunction(r1);
// Tail call to the function-specific construct stub (still in the caller
// Tail call to the array construct stub (still in the caller
// context at this point).
__ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
// Jump to the construct function.
__ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
ArrayConstructorStub array_constructor_stub(masm->isolate());
__ Jump(array_constructor_stub.GetCode(), RelocInfo::CODE_TARGET);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
// Call the constructor with r0, r1, and r3 unmodified.
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread),
......
......@@ -19,12 +19,6 @@ namespace internal {
#define __ ACCESS_MASM(masm)
// Load the built-in Array function from the current context.
static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
// Load the InternalArray function from the native context.
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, result);
}
void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
ExitFrameType exit_frame_type) {
__ Mov(x5, ExternalReference(address, masm->isolate()));
......@@ -116,15 +110,13 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x0 : number of arguments
// -- x1 : array function
// -- lr : return address
// -- sp[...]: constructor arguments
// -----------------------------------
ASM_LOCATION("Builtins::Generate_ArrayConstructor");
Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
// Get the Array function.
GenerateLoadArrayFunction(masm, x1);
if (FLAG_debug_code) {
// Initial map for the builtin Array functions should be maps.
__ Ldr(x10, FieldMemOperand(x1, JSFunction::kPrototypeOrInitialMapOffset));
......@@ -134,9 +126,14 @@ void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// Run the native code for the Array function called as a normal function.
// x2 is the AllocationSite - here undefined.
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
__ Mov(x3, x1);
// If x3 (new target) is undefined, then this is the 'Call' case, so move
// x1 (the constructor) to x3.
__ Cmp(x3, x2);
__ CmovX(x3, x1, eq);
// Run the native code for the Array function called as a normal function.
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
}
......@@ -1221,6 +1218,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
InterpreterPushArgsMode mode) {
DCHECK(mode != InterpreterPushArgsMode::kArrayFunction);
// ----------- S t a t e -------------
// -- x0 : the number of arguments (not including the receiver)
// -- x2 : the address of the first argument to be pushed. Subsequent
......@@ -1240,9 +1238,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
receiver_mode, mode);
// Call the target.
if (mode == InterpreterPushArgsMode::kArrayFunction) {
__ Unreachable();
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
__ Jump(BUILTIN_CODE(masm->isolate(), CallWithSpread),
RelocInfo::CODE_TARGET);
} else {
......@@ -1276,12 +1272,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
if (mode == InterpreterPushArgsMode::kArrayFunction) {
__ AssertFunction(x1);
// Tail call to the function-specific construct stub (still in the caller
// Tail call to the array construct stub (still in the caller
// context at this point).
__ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(x4, FieldMemOperand(x4, SharedFunctionInfo::kConstructStubOffset));
__ Add(x4, x4, Code::kHeaderSize - kHeapObjectTag);
__ Br(x4);
ArrayConstructorStub array_constructor_stub(masm->isolate());
__ Jump(array_constructor_stub.GetCode(), RelocInfo::CODE_TARGET);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
// Call the constructor with x0, x1, and x3 unmodified.
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread),
......
......@@ -1008,6 +1008,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
InterpreterPushArgsMode mode) {
DCHECK(mode != InterpreterPushArgsMode::kArrayFunction);
// ----------- S t a t e -------------
// -- eax : the number of arguments (not including the receiver)
// -- ebx : the address of the first argument to be pushed. Subsequent
......@@ -1050,10 +1051,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
// Call the target.
__ Push(edx); // Re-push return address.
if (mode == InterpreterPushArgsMode::kArrayFunction) {
// This should be unreachable.
__ int3();
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
__ Jump(BUILTIN_CODE(masm->isolate(), CallWithSpread),
RelocInfo::CODE_TARGET);
} else {
......@@ -1198,14 +1196,11 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
}
if (mode == InterpreterPushArgsMode::kArrayFunction) {
// Tail call to the function-specific construct stub (still in the caller
// Tail call to the array construct stub (still in the caller
// context at this point).
__ AssertFunction(edi);
__ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
__ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
__ jmp(ecx);
ArrayConstructorStub array_constructor_stub(masm->isolate());
__ Jump(array_constructor_stub.GetCode(), RelocInfo::CODE_TARGET);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
// Call the constructor with unmodified eax, edi, edx values.
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread),
......@@ -1831,15 +1826,12 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : argc
// -- edi : array function
// -- esp[0] : return address
// -- esp[4] : last argument
// -----------------------------------
Label generic_array_code;
// Get the Array function.
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi);
__ mov(edx, edi);
if (FLAG_debug_code) {
// Initial map for the builtin Array function should be a map.
__ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
......@@ -1850,9 +1842,17 @@ void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
__ Assert(equal, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// Run the native code for the Array function called as a normal function.
// tail call a stub
// ebx is the AllocationSite - here undefined.
__ mov(ebx, masm->isolate()->factory()->undefined_value());
// If edx (new target) is undefined, then this is the 'Call' case, so move
// edi (the constructor) to rdx.
Label call;
__ cmp(edx, ebx);
__ j(not_equal, &call);
__ mov(edx, edi);
// Run the native code for the Array function called as a normal function.
__ bind(&call);
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
}
......
......@@ -82,12 +82,6 @@ void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
// Load the built-in Array function from the current context.
static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
// Load the Array function from the native context.
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, result);
}
void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : number of arguments
......@@ -118,29 +112,33 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : number of arguments
// -- a1 : array function
// -- ra : return address
// -- sp[...]: constructor arguments
// -----------------------------------
Label generic_array_code;
// Get the Array function.
GenerateLoadArrayFunction(masm, a1);
if (FLAG_debug_code) {
// Initial map for the builtin Array functions should be maps.
__ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
__ SmiTst(a2, t0);
__ Assert(ne, AbortReason::kUnexpectedInitialMapForArrayFunction1, t0,
Operand(zero_reg));
__ GetObjectType(a2, a3, t0);
__ GetObjectType(a2, t1, t0);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction2, t0,
Operand(MAP_TYPE));
}
// Run the native code for the Array function called as a normal function.
// Tail call a stub.
__ mov(a3, a1);
// a2 is the AllocationSite - here undefined.
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
// If a3 (new target) is undefined, then this is the 'Call' case, so move
// a1 (the constructor) to a3.
Label call;
__ Branch(&call, ne, a3, Operand(a2));
__ mov(a3, a1);
// Run the native code for the Array function called as a normal function.
__ bind(&call);
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
}
......@@ -1075,6 +1073,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
InterpreterPushArgsMode mode) {
DCHECK(mode != InterpreterPushArgsMode::kArrayFunction);
// ----------- S t a t e -------------
// -- a0 : the number of arguments (not including the receiver)
// -- a2 : the address of the first argument to be pushed. Subsequent
......@@ -1103,10 +1102,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
}
// Call the target.
if (mode == InterpreterPushArgsMode::kArrayFunction) {
// Unreachable code.
__ break_(0xCC);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
__ Jump(BUILTIN_CODE(masm->isolate(), CallWithSpread),
RelocInfo::CODE_TARGET);
} else {
......@@ -1152,11 +1148,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
if (mode == InterpreterPushArgsMode::kArrayFunction) {
__ AssertFunction(a1);
// Tail call to the function-specific construct stub (still in the caller
// Tail call to the array construct stub (still in the caller
// context at this point).
__ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset));
__ Jump(at, t0, Code::kHeaderSize - kHeapObjectTag);
ArrayConstructorStub array_constructor_stub(masm->isolate());
__ Jump(array_constructor_stub.GetCode(), RelocInfo::CODE_TARGET);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
// Call the constructor with a0, a1, and a3 unmodified.
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread),
......
......@@ -82,12 +82,6 @@ void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
// Load the built-in Array function from the current context.
static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
// Load the Array function from the native context.
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, result);
}
void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : number of arguments
......@@ -118,29 +112,33 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : number of arguments
// -- a1 : array function
// -- ra : return address
// -- sp[...]: constructor arguments
// -----------------------------------
Label generic_array_code;
// Get the Array function.
GenerateLoadArrayFunction(masm, a1);
if (FLAG_debug_code) {
// Initial map for the builtin Array functions should be maps.
__ Ld(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
__ SmiTst(a2, a4);
__ Assert(ne, AbortReason::kUnexpectedInitialMapForArrayFunction1, a4,
Operand(zero_reg));
__ GetObjectType(a2, a3, a4);
__ GetObjectType(a2, t0, a4);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction2, a4,
Operand(MAP_TYPE));
}
// Run the native code for the Array function called as a normal function.
// Tail call a stub.
__ mov(a3, a1);
// a2 is the AllocationSite - here undefined.
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
// If a3 (new target) is undefined, then this is the 'Call' case, so move
// a1 (the constructor) to a3.
Label call;
__ Branch(&call, ne, a3, Operand(a2));
__ mov(a3, a1);
// Run the native code for the Array function called as a normal function.
__ bind(&call);
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
}
......@@ -1072,6 +1070,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
InterpreterPushArgsMode mode) {
DCHECK(mode != InterpreterPushArgsMode::kArrayFunction);
// ----------- S t a t e -------------
// -- a0 : the number of arguments (not including the receiver)
// -- a2 : the address of the first argument to be pushed. Subsequent
......@@ -1100,10 +1099,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
}
// Call the target.
if (mode == InterpreterPushArgsMode::kArrayFunction) {
// Unreachable code.
__ break_(0xCC);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
__ Jump(BUILTIN_CODE(masm->isolate(), CallWithSpread),
RelocInfo::CODE_TARGET);
} else {
......@@ -1151,10 +1147,8 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
// Tail call to the function-specific construct stub (still in the caller
// context at this point).
__ Ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ Ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kConstructStubOffset));
__ Daddu(at, a4, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(at);
ArrayConstructorStub array_constructor_stub(masm->isolate());
__ Jump(array_constructor_stub.GetCode(), RelocInfo::CODE_TARGET);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
// Call the constructor with a0, a1, and a3 unmodified.
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread),
......
......@@ -81,12 +81,6 @@ void Builtins::Generate_AdaptorWithBuiltinExitFrame(MacroAssembler* masm) {
AdaptorWithExitFrameType(masm, BUILTIN_EXIT);
}
// Load the built-in Array function from the current context.
static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
// Load the Array function from the current native context.
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, result);
}
void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : number of arguments
......@@ -116,27 +110,32 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : number of arguments
// -- r4 : array function
// -- lr : return address
// -- sp[...]: constructor arguments
// -----------------------------------
Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
// Get the Array function.
GenerateLoadArrayFunction(masm, r4);
if (FLAG_debug_code) {
// Initial map for the builtin Array functions should be maps.
__ LoadP(r5, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
__ TestIfSmi(r5, r0);
__ Assert(ne, AbortReason::kUnexpectedInitialMapForArrayFunction, cr0);
__ CompareObjectType(r5, r6, r7, MAP_TYPE);
__ CompareObjectType(r5, r7, r8, MAP_TYPE);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// r5 is the AllocationSite - here undefined.
__ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
// If r6 (new target) is undefined, then this is the 'Call' case, so move
// r4 (the constructor) to r6.
Label call;
__ cmp(r6, r5);
__ bne(&call);
__ mr(r6, r4);
// Run the native code for the Array function called as a normal function.
// tail call a stub
__ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
__ bind(&call);
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
}
......@@ -1101,6 +1100,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
InterpreterPushArgsMode mode) {
DCHECK(mode != InterpreterPushArgsMode::kArrayFunction);
// ----------- S t a t e -------------
// -- r3 : the number of arguments (not including the receiver)
// -- r5 : the address of the first argument to be pushed. Subsequent
......@@ -1130,10 +1130,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
}
// Call the target.
if (mode == InterpreterPushArgsMode::kArrayFunction) {
// Unreachable Code.
__ bkpt(0);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
__ Jump(BUILTIN_CODE(masm->isolate(), CallWithSpread),
RelocInfo::CODE_TARGET);
} else {
......@@ -1182,13 +1179,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
if (mode == InterpreterPushArgsMode::kArrayFunction) {
__ AssertFunction(r4);
// Tail call to the function-specific construct stub (still in the caller
// Tail call to the array construct stub (still in the caller
// context at this point).
__ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kConstructStubOffset));
// Jump to the construct function.
__ addi(ip, r7, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(ip);
ArrayConstructorStub array_constructor_stub(masm->isolate());
__ Jump(array_constructor_stub.GetCode(), RelocInfo::CODE_TARGET);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
// Call the constructor with r3, r4, and r6 unmodified.
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread),
......
......@@ -116,6 +116,7 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : number of arguments
// -- r3 : array function
// -- lr : return address
// -- sp[...]: constructor arguments
// -----------------------------------
......@@ -129,14 +130,21 @@ void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
__ LoadP(r4, FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset));
__ TestIfSmi(r4);
__ Assert(ne, AbortReason::kUnexpectedInitialMapForArrayFunction, cr0);
__ CompareObjectType(r4, r5, r6, MAP_TYPE);
__ CompareObjectType(r4, r6, r7, MAP_TYPE);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// r4 is the AllocationSite - here undefined.
__ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
// If r5 (new target) is undefined, then this is the 'Call' case, so move
// r3 (the constructor) to r5.
Label call;
__ CmpP(r5, r4);
__ bne(&call);
__ LoadRR(r5, r3);
// Run the native code for the Array function called as a normal function.
// tail call a stub
__ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
__ bind(&call);
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
}
......@@ -1103,6 +1111,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
InterpreterPushArgsMode mode) {
DCHECK(mode != InterpreterPushArgsMode::kArrayFunction);
// ----------- S t a t e -------------
// -- r2 : the number of arguments (not including the receiver)
// -- r4 : the address of the first argument to be pushed. Subsequent
......@@ -1130,10 +1139,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
}
// Call the target.
if (mode == InterpreterPushArgsMode::kArrayFunction) {
// Unreachable Code.
__ bkpt(0);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
__ Jump(BUILTIN_CODE(masm->isolate(), CallWithSpread),
RelocInfo::CODE_TARGET);
} else {
......@@ -1182,13 +1188,10 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
if (mode == InterpreterPushArgsMode::kArrayFunction) {
__ AssertFunction(r3);
// Tail call to the function-specific construct stub (still in the caller
// Tail call to the array construct stub (still in the caller
// context at this point).
__ LoadP(r6, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r6, FieldMemOperand(r6, SharedFunctionInfo::kConstructStubOffset));
// Jump to the construct function.
__ AddP(ip, r6, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(ip);
ArrayConstructorStub array_constructor_stub(masm->isolate());
__ Jump(array_constructor_stub.GetCode(), RelocInfo::CODE_TARGET);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
// Call the constructor with r2, r3, and r5 unmodified.
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread),
......
......@@ -1076,6 +1076,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
InterpreterPushArgsMode mode) {
DCHECK(mode != InterpreterPushArgsMode::kArrayFunction);
// ----------- S t a t e -------------
// -- rax : the number of arguments (not including the receiver)
// -- rbx : the address of the first argument to be pushed. Subsequent
......@@ -1112,10 +1113,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
// Call the target.
__ PushReturnAddressFrom(kScratchRegister); // Re-push return address.
if (mode == InterpreterPushArgsMode::kArrayFunction) {
// This should be unreachable.
__ int3();
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
__ Jump(BUILTIN_CODE(masm->isolate(), CallWithSpread),
RelocInfo::CODE_TARGET);
} else {
......@@ -1171,15 +1169,12 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
}
if (mode == InterpreterPushArgsMode::kArrayFunction) {
// Tail call to the function-specific construct stub (still in the caller
// Tail call to the array construct stub (still in the caller
// context at this point).
__ AssertFunction(rdi);
__ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
__ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
// Jump to the constructor function (rax, rbx, rdx passed on).
__ jmp(rcx);
ArrayConstructorStub array_constructor_stub(masm->isolate());
__ Jump(array_constructor_stub.GetCode(), RelocInfo::CODE_TARGET);
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
// Call the constructor (rax, rdx, rdi passed on).
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructWithSpread),
......@@ -1816,14 +1811,12 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : argc
// -- rdi : array function
// -- rsp[0] : return address
// -- rsp[8] : last argument
// -----------------------------------
Label generic_array_code;
// Get the Array function.
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, rdi);
if (FLAG_debug_code) {
// Initial map for the builtin Array functions should be maps.
__ movp(rbx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset));
......@@ -1835,10 +1828,17 @@ void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
__ Check(equal, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// rbx is the AllocationSite - here undefined.
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
// If rdx (new target) is undefined, then this is the 'Call' case, so move
// rdi (the constructor) to rdx.
Label call;
__ cmpp(rdx, rbx);
__ j(not_equal, &call);
__ movp(rdx, rdi);
// Run the native code for the Array function called as a normal function.
// tail call a stub
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
__ bind(&call);
ArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
}
......
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