Commit 1c1590e8 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [turbofan] Switch passing of new.target to register.

Port 7c45b005

Original commit message:
    This passes the new.target value in a register instead of through a
    side-channel via the construct stub. Note that only TurboFan code uses
    the register value so far, but unoptimized code will be switched soon.

R=mstarzinger@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=v8:4544
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#32231}
parent 9b3dff93
...@@ -3527,7 +3527,8 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { ...@@ -3527,7 +3527,8 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
// The number of arguments is stored in receiver which is r3, as expected // The number of arguments is stored in receiver which is r3, as expected
// by InvokeFunction. // by InvokeFunction.
ParameterCount actual(receiver); ParameterCount actual(receiver);
__ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator); __ InvokeFunction(function, no_reg, actual, CALL_FUNCTION,
safepoint_generator);
} }
...@@ -3954,7 +3955,7 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { ...@@ -3954,7 +3955,7 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
LPointerMap* pointers = instr->pointer_map(); LPointerMap* pointers = instr->pointer_map();
SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
ParameterCount count(instr->arity()); ParameterCount count(instr->arity());
__ InvokeFunction(r4, count, CALL_FUNCTION, generator); __ InvokeFunction(r4, no_reg, count, CALL_FUNCTION, generator);
} else { } else {
CallKnownFunction(known_function, CallKnownFunction(known_function,
instr->hydrogen()->formal_parameter_count(), instr->hydrogen()->formal_parameter_count(),
......
...@@ -305,14 +305,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -305,14 +305,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
static void CallRuntimePassFunction(MacroAssembler* masm, static void CallRuntimePassFunction(MacroAssembler* masm,
Runtime::FunctionId function_id) { Runtime::FunctionId function_id) {
// ----------- S t a t e -------------
// -- r4 : target function (preserved for callee)
// -- r6 : new target (preserved for callee)
// -----------------------------------
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Push a copy of the function onto the stack. // Push a copy of the target function and the new target.
// Push function as parameter to the runtime call. // Push function as parameter to the runtime call.
__ Push(r4, r4); __ Push(r4, r6, r4);
__ CallRuntime(function_id, 1); __ CallRuntime(function_id, 1);
// Restore reciever. // Restore target function and new target.
__ Pop(r4); __ Pop(r4, r6);
} }
...@@ -539,6 +544,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, ...@@ -539,6 +544,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
// r3: number of arguments // r3: number of arguments
// r4: constructor function // r4: constructor function
// r5: address of last argument (caller sp) // r5: address of last argument (caller sp)
// r6: new target
// cr0: condition indicating whether r3 is zero // cr0: condition indicating whether r3 is zero
// sp[0]: receiver // sp[0]: receiver
// sp[1]: receiver // sp[1]: receiver
...@@ -559,13 +565,14 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, ...@@ -559,13 +565,14 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
// Call the function. // Call the function.
// r3: number of arguments // r3: number of arguments
// r4: constructor function // r4: constructor function
// r6: new target
if (is_api_function) { if (is_api_function) {
__ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
Handle<Code> code = masm->isolate()->builtins()->HandleApiCallConstruct(); Handle<Code> code = masm->isolate()->builtins()->HandleApiCallConstruct();
__ Call(code, RelocInfo::CODE_TARGET); __ Call(code, RelocInfo::CODE_TARGET);
} else { } else {
ParameterCount actual(r3); ParameterCount actual(r3);
__ InvokeFunction(r4, actual, CALL_FUNCTION, NullCallWrapper()); __ InvokeFunction(r4, r6, actual, CALL_FUNCTION, NullCallWrapper());
} }
// Store offset of return address for deoptimizer. // Store offset of return address for deoptimizer.
...@@ -984,15 +991,16 @@ static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) { ...@@ -984,15 +991,16 @@ static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// the runtime: // the runtime:
// r3 - contains return address (beginning of patch sequence) // r3 - contains return address (beginning of patch sequence)
// r4 - isolate // r4 - isolate
// r6 - new target
// lr - return address // lr - return address
FrameScope scope(masm, StackFrame::MANUAL); FrameScope scope(masm, StackFrame::MANUAL);
__ mflr(r0); __ mflr(r0);
__ MultiPush(r0.bit() | r3.bit() | r4.bit() | fp.bit()); __ MultiPush(r0.bit() | r3.bit() | r4.bit() | r6.bit() | fp.bit());
__ PrepareCallCFunction(2, 0, r5); __ PrepareCallCFunction(2, 0, r5);
__ mov(r4, Operand(ExternalReference::isolate_address(masm->isolate()))); __ mov(r4, Operand(ExternalReference::isolate_address(masm->isolate())));
__ CallCFunction( __ CallCFunction(
ExternalReference::get_make_code_young_function(masm->isolate()), 2); ExternalReference::get_make_code_young_function(masm->isolate()), 2);
__ MultiPop(r0.bit() | r3.bit() | r4.bit() | fp.bit()); __ MultiPop(r0.bit() | r3.bit() | r4.bit() | r6.bit() | fp.bit());
__ mtlr(r0); __ mtlr(r0);
__ mr(ip, r3); __ mr(ip, r3);
__ Jump(ip); __ Jump(ip);
...@@ -1025,16 +1033,17 @@ void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { ...@@ -1025,16 +1033,17 @@ void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
// the runtime: // the runtime:
// r3 - contains return address (beginning of patch sequence) // r3 - contains return address (beginning of patch sequence)
// r4 - isolate // r4 - isolate
// r6 - new target
// lr - return address // lr - return address
FrameScope scope(masm, StackFrame::MANUAL); FrameScope scope(masm, StackFrame::MANUAL);
__ mflr(r0); __ mflr(r0);
__ MultiPush(r0.bit() | r3.bit() | r4.bit() | fp.bit()); __ MultiPush(r0.bit() | r3.bit() | r4.bit() | r6.bit() | fp.bit());
__ PrepareCallCFunction(2, 0, r5); __ PrepareCallCFunction(2, 0, r5);
__ mov(r4, Operand(ExternalReference::isolate_address(masm->isolate()))); __ mov(r4, Operand(ExternalReference::isolate_address(masm->isolate())));
__ CallCFunction( __ CallCFunction(
ExternalReference::get_mark_code_as_executed_function(masm->isolate()), ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
2); 2);
__ MultiPop(r0.bit() | r3.bit() | r4.bit() | fp.bit()); __ MultiPop(r0.bit() | r3.bit() | r4.bit() | r6.bit() | fp.bit());
__ mtlr(r0); __ mtlr(r0);
__ mr(ip, r3); __ mr(ip, r3);
...@@ -1690,10 +1699,10 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -1690,10 +1699,10 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
#if !V8_TARGET_ARCH_PPC64 #if !V8_TARGET_ARCH_PPC64
__ SmiUntag(r5); __ SmiUntag(r5);
#endif #endif
__ LoadP(r6, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); __ LoadP(r7, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
ParameterCount actual(r3); ParameterCount actual(r3);
ParameterCount expected(r5); ParameterCount expected(r5);
__ InvokeCode(r6, expected, actual, JUMP_FUNCTION, NullCallWrapper()); __ InvokeCode(r7, no_reg, expected, actual, JUMP_FUNCTION, NullCallWrapper());
// The function is a "classConstructor", need to raise an exception. // The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor); __ bind(&class_constructor);
......
...@@ -1085,12 +1085,20 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, ...@@ -1085,12 +1085,20 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
} }
void MacroAssembler::InvokeCode(Register code, const ParameterCount& expected, void MacroAssembler::InvokeCode(Register code, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag, const ParameterCount& actual, InvokeFlag flag,
const CallWrapper& call_wrapper) { const CallWrapper& call_wrapper) {
// You can't call a function without a valid frame. // You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame()); DCHECK(flag == JUMP_FUNCTION || has_frame());
// Ensure new target is passed in the correct register. Otherwise clear the
// appropriate register in case new target is not given.
DCHECK_IMPLIES(new_target.is_valid(), new_target.is(r6));
if (!new_target.is_valid()) {
LoadRoot(r6, Heap::kUndefinedValueRootIndex);
}
Label done; Label done;
bool definitely_mismatches = false; bool definitely_mismatches = false;
InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, InvokePrologue(expected, actual, &done, &definitely_mismatches, flag,
...@@ -1112,7 +1120,8 @@ void MacroAssembler::InvokeCode(Register code, const ParameterCount& expected, ...@@ -1112,7 +1120,8 @@ void MacroAssembler::InvokeCode(Register code, const ParameterCount& expected,
} }
void MacroAssembler::InvokeFunction(Register fun, const ParameterCount& actual, void MacroAssembler::InvokeFunction(Register fun, Register new_target,
const ParameterCount& actual,
InvokeFlag flag, InvokeFlag flag,
const CallWrapper& call_wrapper) { const CallWrapper& call_wrapper) {
// You can't call a function without a valid frame. // You can't call a function without a valid frame.
...@@ -1135,7 +1144,7 @@ void MacroAssembler::InvokeFunction(Register fun, const ParameterCount& actual, ...@@ -1135,7 +1144,7 @@ void MacroAssembler::InvokeFunction(Register fun, const ParameterCount& actual,
LoadP(code_reg, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); LoadP(code_reg, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
ParameterCount expected(expected_reg); ParameterCount expected(expected_reg);
InvokeCode(code_reg, expected, actual, flag, call_wrapper); InvokeCode(code_reg, new_target, expected, actual, flag, call_wrapper);
} }
...@@ -1157,7 +1166,7 @@ void MacroAssembler::InvokeFunction(Register function, ...@@ -1157,7 +1166,7 @@ void MacroAssembler::InvokeFunction(Register function,
// allow recompilation to take effect without changing any of the // allow recompilation to take effect without changing any of the
// call sites. // call sites.
LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
InvokeCode(ip, expected, actual, flag, call_wrapper); InvokeCode(ip, no_reg, expected, actual, flag, call_wrapper);
} }
......
...@@ -554,14 +554,15 @@ class MacroAssembler : public Assembler { ...@@ -554,14 +554,15 @@ class MacroAssembler : public Assembler {
// JavaScript invokes // JavaScript invokes
// Invoke the JavaScript function code by either calling or jumping. // Invoke the JavaScript function code by either calling or jumping.
void InvokeCode(Register code, const ParameterCount& expected, void InvokeCode(Register code, Register new_target,
const ParameterCount& actual, InvokeFlag flag, const ParameterCount& expected, const ParameterCount& actual,
const CallWrapper& call_wrapper); InvokeFlag flag, const CallWrapper& call_wrapper);
// Invoke the JavaScript function in the given register. Changes the // Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking. // current context to the context in the function before invoking.
void InvokeFunction(Register function, const ParameterCount& actual, void InvokeFunction(Register function, Register new_target,
InvokeFlag flag, const CallWrapper& call_wrapper); const ParameterCount& actual, InvokeFlag flag,
const CallWrapper& call_wrapper);
void InvokeFunction(Register function, const ParameterCount& expected, void InvokeFunction(Register function, const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag, const ParameterCount& actual, InvokeFlag flag,
......
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