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