Commit a02f7e6f authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: Switch CallConstructStub to take new.target in register.

Port 1d9d8957

Original commit message:
    This changes the calling convention of the CallConstructStub to take
    the original constructor (i.e. new.target in JS-speak) in a register
    instead of magically via the operand stack. For optimizing compilers
    the operand stack doesn't exist, hence cannot be peeked into.

R=mstarzinger@chromium.org, dstence@us.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1230103004

Cr-Commit-Position: refs/heads/master@{#29702}
parent 40c38c5a
...@@ -1539,9 +1539,7 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1539,9 +1539,7 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
__ li(r4, Operand::Zero()); __ li(r4, Operand::Zero());
__ Push(r3, r4); // limit and initial index. __ Push(r3, r4); // limit and initial index.
// Push newTarget and callee functions // Push the constructor function as callee
__ LoadP(r3, MemOperand(fp, kNewTargetOffset));
__ push(r3);
__ LoadP(r3, MemOperand(fp, kFunctionOffset)); __ LoadP(r3, MemOperand(fp, kFunctionOffset));
__ push(r3); __ push(r3);
...@@ -1552,13 +1550,12 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1552,13 +1550,12 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
// Use undefined feedback vector // Use undefined feedback vector
__ LoadRoot(r5, Heap::kUndefinedValueRootIndex); __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
__ LoadP(r4, MemOperand(fp, kFunctionOffset)); __ LoadP(r4, MemOperand(fp, kFunctionOffset));
__ LoadP(r7, MemOperand(fp, kNewTargetOffset));
// Call the function. // Call the function.
CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
__ Drop(1);
// Leave internal frame. // Leave internal frame.
} }
__ addi(sp, sp, Operand(kStackSize * kPointerSize)); __ addi(sp, sp, Operand(kStackSize * kPointerSize));
......
...@@ -2782,18 +2782,25 @@ void CallConstructStub::Generate(MacroAssembler* masm) { ...@@ -2782,18 +2782,25 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
// r3 : number of arguments // r3 : number of arguments
// r4 : the function to call // r4 : the function to call
// r5 : feedback vector // r5 : feedback vector
// r6 : (only if r5 is not the megamorphic symbol) slot in feedback // r6 : slot in feedback vector (Smi, for RecordCallTarget)
// vector (Smi) // r7 : original constructor (for IsSuperConstructorCall)
Label slow, non_function_call; Label slow, non_function_call;
// Check that the function is not a smi. // Check that the function is not a smi.
__ JumpIfSmi(r4, &non_function_call); __ JumpIfSmi(r4, &non_function_call);
// Check that the function is a JSFunction. // Check that the function is a JSFunction.
__ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE); __ CompareObjectType(r4, r8, r8, JS_FUNCTION_TYPE);
__ bne(&slow); __ bne(&slow);
if (RecordCallTarget()) { if (RecordCallTarget()) {
if (IsSuperConstructorCall()) {
__ push(r7);
}
// TODO(mstarzinger): Consider tweaking target recording to avoid push/pop.
GenerateRecordCallTarget(masm); GenerateRecordCallTarget(masm);
if (IsSuperConstructorCall()) {
__ pop(r7);
}
__ SmiToPtrArrayOffset(r8, r6); __ SmiToPtrArrayOffset(r8, r6);
__ add(r8, r5, r8); __ add(r8, r5, r8);
...@@ -2823,9 +2830,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) { ...@@ -2823,9 +2830,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
// Pass function as original constructor. // Pass function as original constructor.
if (IsSuperConstructorCall()) { if (IsSuperConstructorCall()) {
__ ShiftLeftImm(r7, r3, Operand(kPointerSizeLog2)); __ mr(r6, r7);
__ addi(r7, r7, Operand(kPointerSize));
__ LoadPX(r6, MemOperand(sp, r7));
} else { } else {
__ mr(r6, r4); __ mr(r6, r4);
} }
...@@ -2840,11 +2845,11 @@ void CallConstructStub::Generate(MacroAssembler* masm) { ...@@ -2840,11 +2845,11 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
// r3: number of arguments // r3: number of arguments
// r4: called object // r4: called object
// r7: object type // r8: object type
Label do_call; Label do_call;
__ bind(&slow); __ bind(&slow);
STATIC_ASSERT(JS_FUNCTION_PROXY_TYPE < 0xffffu); STATIC_ASSERT(JS_FUNCTION_PROXY_TYPE < 0xffffu);
__ cmpi(r7, Operand(JS_FUNCTION_PROXY_TYPE)); __ cmpi(r8, Operand(JS_FUNCTION_PROXY_TYPE));
__ bne(&non_function_call); __ bne(&non_function_call);
__ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); __ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
__ b(&do_call); __ b(&do_call);
......
...@@ -3384,9 +3384,6 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { ...@@ -3384,9 +3384,6 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
expr->expression()->AsSuperCallReference(); expr->expression()->AsSuperCallReference();
DCHECK_NOT_NULL(super_call_ref); DCHECK_NOT_NULL(super_call_ref);
VariableProxy* new_target_proxy = super_call_ref->new_target_var();
VisitForStackValue(new_target_proxy);
EmitLoadSuperConstructor(super_call_ref); EmitLoadSuperConstructor(super_call_ref);
__ push(result_register()); __ push(result_register());
...@@ -3401,6 +3398,10 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { ...@@ -3401,6 +3398,10 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
// constructor invocation. // constructor invocation.
SetConstructCallPosition(expr); SetConstructCallPosition(expr);
// Load original constructor into r7.
VisitForAccumulatorValue(super_call_ref->new_target_var());
__ mr(r7, result_register());
// Load function and argument count into r1 and r0. // Load function and argument count into r1 and r0.
__ mov(r3, Operand(arg_count)); __ mov(r3, Operand(arg_count));
__ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize));
...@@ -3421,8 +3422,6 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { ...@@ -3421,8 +3422,6 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
__ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
__ Drop(1);
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot()); EmitInitializeThisAfterSuper(super_call_ref, expr->CallFeedbackICSlot());
...@@ -4343,6 +4342,9 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { ...@@ -4343,6 +4342,9 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
__ mr(r4, result_register()); __ mr(r4, result_register());
__ Push(r4); __ Push(r4);
// Load original constructor into r7.
__ LoadP(r7, MemOperand(sp, 1 * kPointerSize));
// Check if the calling frame is an arguments adaptor frame. // Check if the calling frame is an arguments adaptor frame.
Label adaptor_frame, args_set_up, runtime; Label adaptor_frame, args_set_up, runtime;
__ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
......
...@@ -169,11 +169,11 @@ void CallConstructDescriptor::InitializePlatformSpecific( ...@@ -169,11 +169,11 @@ void CallConstructDescriptor::InitializePlatformSpecific(
// r3 : number of arguments // r3 : number of arguments
// r4 : the function to call // r4 : the function to call
// r5 : feedback vector // r5 : feedback vector
// r6 : (only if r5 is not the megamorphic symbol) slot in feedback // r6 : slot in feedback vector (Smi, for RecordCallTarget)
// vector (Smi) // r7 : original constructor (for IsSuperConstructorCall)
// TODO(turbofan): So far we don't gather type feedback and hence skip the // TODO(turbofan): So far we don't gather type feedback and hence skip the
// slot parameter, but ArrayConstructStub needs the vector to be undefined. // slot parameter, but ArrayConstructStub needs the vector to be undefined.
Register registers[] = {r3, r4, r5}; Register registers[] = {r3, r4, r7, r5};
data->InitializePlatformSpecific(arraysize(registers), registers); 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