Commit 2703b06e authored by bjaideep's avatar bjaideep Committed by Commit bot

PPC/s390: [turbofan] Correct lazy deopt by {JSCreate} operation.

Port 6ee0b6ce

Original Commit Message:

    This adds support for deoptimizing into the JSConstructStub after the
    receiver instantiation but before the actual constructor invocation.
    Such a deoptimization point is needed for cases where instantiation
    might be observed (e.g. when new.target is a proxy) and hence might
    trigger a deopt.

    We use this new deoptimization point for the "after" frame-state the
    inliner attaches to {JSCreate} nodes being inserted when constructor
    calls are being inlined.

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

Review-Url: https://codereview.chromium.org/2690213002
Cr-Commit-Position: refs/heads/master@{#43171}
parent a386eb4f
......@@ -560,6 +560,7 @@ namespace {
void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
bool create_implicit_receiver,
bool check_derived_construct) {
Label post_instantiation_deopt_entry;
// ----------- S t a t e -------------
// -- r3 : number of arguments
// -- r4 : constructor function
......@@ -608,6 +609,9 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
__ Push(r7, r7);
}
// Deoptimizer re-enters stub code here.
__ bind(&post_instantiation_deopt_entry);
// Set up pointer to last argument.
__ addi(r5, fp, Operand(StandardFrameConstants::kCallerSPOffset));
......@@ -643,7 +647,8 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
// Store offset of return address for deoptimizer.
if (create_implicit_receiver && !is_api_function) {
masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset(
masm->pc_offset());
}
// Restore context from the frame.
......@@ -708,6 +713,34 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
__ IncrementCounter(isolate->counters()->constructed_objects(), 1, r4, r5);
}
__ blr();
// Store offset of trampoline address for deoptimizer. This is the bailout
// point after the receiver instantiation but before the function invocation.
// We need to restore some registers in order to continue the above code.
if (create_implicit_receiver && !is_api_function) {
masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset(
masm->pc_offset());
// ----------- S t a t e -------------
// -- r3 : newly allocated object
// -- sp[0] : constructor function
// -----------------------------------
__ pop(r4);
__ Push(r3, r3);
// Retrieve smi-tagged arguments count from the stack.
__ LoadP(r3, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
__ SmiUntag(r3);
// Retrieve the new target value from the stack. This was placed into the
// frame description in place of the receiver by the optimizing compiler.
__ addi(r6, fp, Operand(StandardFrameConstants::kCallerSPOffset));
__ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2));
__ LoadPX(r6, MemOperand(r6, ip));
// Continue with constructor function invocation.
__ b(&post_instantiation_deopt_entry);
}
}
} // namespace
......
......@@ -556,6 +556,7 @@ namespace {
void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
bool create_implicit_receiver,
bool check_derived_construct) {
Label post_instantiation_deopt_entry;
// ----------- S t a t e -------------
// -- r2 : number of arguments
// -- r3 : constructor function
......@@ -606,6 +607,9 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
__ Push(r6, r6);
}
// Deoptimizer re-enters stub code here.
__ bind(&post_instantiation_deopt_entry);
// Set up pointer to last argument.
__ la(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset));
......@@ -641,7 +645,8 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
// Store offset of return address for deoptimizer.
if (create_implicit_receiver && !is_api_function) {
masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset(
masm->pc_offset());
}
// Restore context from the frame.
......@@ -707,6 +712,35 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
__ IncrementCounter(isolate->counters()->constructed_objects(), 1, r3, r4);
}
__ Ret();
// Store offset of trampoline address for deoptimizer. This is the bailout
// point after the receiver instantiation but before the function invocation.
// We need to restore some registers in order to continue the above code.
if (create_implicit_receiver && !is_api_function) {
masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset(
masm->pc_offset());
// ----------- S t a t e -------------
// -- r2 : newly allocated object
// -- sp[0] : constructor function
// -----------------------------------
__ pop(r3);
__ Push(r2, r2);
// Retrieve smi-tagged arguments count from the stack.
__ LoadP(r2, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
__ SmiUntag(r2);
// Retrieve the new target value from the stack. This was placed into the
// frame description in place of the receiver by the optimizing compiler.
__ la(r5, MemOperand(fp, StandardFrameConstants::kCallerSPOffset));
__ ShiftLeftP(ip, r2, Operand(kPointerSizeLog2));
__ LoadP(r5, MemOperand(r2, ip));
// Continue with constructor function invocation.
__ b(&post_instantiation_deopt_entry);
}
}
} // namespace
......
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