Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
Reland of [interpreter] Add explicit OSR polling bytecode. (patchset #1
Browse files Browse the repository at this point in the history
… id:1 of https://codereview.chromium.org/2184553003/ )

Reason for revert:
Fix has been landed.

Original issue's description:
> Revert of [interpreter] Add explicit OSR polling bytecode. (patchset #6 id:100001 of https://codereview.chromium.org/2172233002/ )
>
> Reason for revert:
> Bunch of breakages. Maybe bad interaction with https://chromium.googlesource.com/v8/v8/+/e520e5da5550f0d1a975e87d6e66a2edecbb0c8e ?
>
> E.g.:
> https://build.chromium.org/p/client.v8/builders/V8%20Linux64/builds/11607
>
> Original issue's description:
> > [interpreter] Add explicit OSR polling bytecode.
> >
> > This adds an explicit {OsrPoll} bytecode into every loop header which
> > triggers on-stack replacement when armed. Note that each such bytecode
> > stores the static loop depths as an operand, and hence can be armed for
> > specific loop depths.
> >
> > This also adds builtin code that triggers OSR compilation and switches
> > execution over to optimized code in case compilation succeeds. In case
> > compilation fails, the bytecode dispatch just continues unhindered.
> >
> > R=rmcilroy@chromium.org
> > TEST=mjsunit/ignition/osr-from-bytecode
> > BUG=v8:4764
> >
> > Committed: https://crrev.com/a55beb68e0ededb3773affa294a71edc50621458
> > Cr-Commit-Position: refs/heads/master@{#38043}
>
> TBR=rmcilroy@chromium.org,mstarzinger@chromium.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=v8:4764
>
> Committed: https://crrev.com/439aa2c6d708bfd95db725bd6f97c4c49bbc51fc
> Cr-Commit-Position: refs/heads/master@{#38044}

TBR=rmcilroy@chromium.org,machenbach@chromium.org
BUG=v8:4764

Review-Url: https://codereview.chromium.org/2184713002
Cr-Commit-Position: refs/heads/master@{#38056}
  • Loading branch information
mstarzinger authored and Commit bot committed Jul 26, 2016
1 parent 968d3bc commit e1ad114
Show file tree
Hide file tree
Showing 23 changed files with 300 additions and 38 deletions.
27 changes: 24 additions & 3 deletions src/builtins/arm/builtins-arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1723,24 +1723,37 @@ void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kThrowIllegalInvocation);
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
bool has_handler_frame) {
// Lookup the function in the JavaScript frame.
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
if (has_handler_frame) {
__ ldr(r0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ ldr(r0, MemOperand(r0, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
}

{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Pass function as argument.
__ push(r0);
__ CallRuntime(Runtime::kCompileForOnStackReplacement);
}

// If the code object is null, just return to the unoptimized code.
// If the code object is null, just return to the caller.
Label skip;
__ cmp(r0, Operand(Smi::FromInt(0)));
__ b(ne, &skip);
__ Ret();

__ bind(&skip);

// Drop any potential handler frame that is be sitting on top of the actual
// JavaScript frame. This is the case then OSR is triggered from bytecode.
if (has_handler_frame) {
__ LeaveFrame(StackFrame::STUB);
}

// Load deoptimization data from the code object.
// <deopt_data> = <code>[#deoptimization_data_offset]
__ ldr(r1, FieldMemOperand(r0, Code::kDeoptimizationDataOffset));
Expand All @@ -1767,6 +1780,14 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
}
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, false);
}

void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, true);
}

// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
Expand Down
27 changes: 24 additions & 3 deletions src/builtins/arm64/builtins-arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1735,23 +1735,36 @@ void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kThrowIllegalInvocation);
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
bool has_handler_frame) {
// Lookup the function in the JavaScript frame.
__ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
if (has_handler_frame) {
__ Ldr(x0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ Ldr(x0, MemOperand(x0, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
}

{
FrameScope scope(masm, StackFrame::INTERNAL);
// Pass function as argument.
__ Push(x0);
__ CallRuntime(Runtime::kCompileForOnStackReplacement);
}

// If the code object is null, just return to the unoptimized code.
// If the code object is null, just return to the caller.
Label skip;
__ CompareAndBranch(x0, Smi::FromInt(0), ne, &skip);
__ Ret();

__ Bind(&skip);

// Drop any potential handler frame that is be sitting on top of the actual
// JavaScript frame. This is the case then OSR is triggered from bytecode.
if (has_handler_frame) {
__ LeaveFrame(StackFrame::STUB);
}

// Load deoptimization data from the code object.
// <deopt_data> = <code>[#deoptimization_data_offset]
__ Ldr(x1, MemOperand(x0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
Expand All @@ -1771,6 +1784,14 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
__ Ret();
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, false);
}

void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, true);
}

// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
Expand Down
1 change: 1 addition & 0 deletions src/builtins/builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ namespace internal {
ASM(InterpreterPushArgsAndTailCall) \
ASM(InterpreterPushArgsAndTailCallFunction) \
ASM(InterpreterEnterBytecodeDispatch) \
ASM(InterpreterOnStackReplacement) \
\
/* Code life-cycle */ \
ASM(CompileLazy) \
Expand Down
27 changes: 24 additions & 3 deletions src/builtins/ia32/builtins-ia32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2968,9 +2968,16 @@ void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
}
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
bool has_handler_frame) {
// Lookup the function in the JavaScript frame.
__ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
if (has_handler_frame) {
__ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
__ mov(eax, Operand(eax, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
}

{
FrameScope scope(masm, StackFrame::INTERNAL);
// Pass function as argument.
Expand All @@ -2979,13 +2986,19 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
}

Label skip;
// If the code object is null, just return to the unoptimized code.
// If the code object is null, just return to the caller.
__ cmp(eax, Immediate(0));
__ j(not_equal, &skip, Label::kNear);
__ ret(0);

__ bind(&skip);

// Drop any potential handler frame that is be sitting on top of the actual
// JavaScript frame. This is the case then OSR is triggered from bytecode.
if (has_handler_frame) {
__ leave();
}

// Load deoptimization data from the code object.
__ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag));

Expand All @@ -3005,6 +3018,14 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
__ ret(0);
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, false);
}

void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, true);
}

#undef __
} // namespace internal
} // namespace v8
Expand Down
27 changes: 24 additions & 3 deletions src/builtins/mips/builtins-mips.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1723,19 +1723,32 @@ void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kThrowIllegalInvocation);
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
bool has_handler_frame) {
// Lookup the function in the JavaScript frame.
__ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
if (has_handler_frame) {
__ lw(a0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ lw(a0, MemOperand(a0, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
}

{
FrameScope scope(masm, StackFrame::INTERNAL);
// Pass function as argument.
__ push(a0);
__ CallRuntime(Runtime::kCompileForOnStackReplacement);
}

// If the code object is null, just return to the unoptimized code.
// If the code object is null, just return to the caller.
__ Ret(eq, v0, Operand(Smi::FromInt(0)));

// Drop any potential handler frame that is be sitting on top of the actual
// JavaScript frame. This is the case then OSR is triggered from bytecode.
if (has_handler_frame) {
__ LeaveFrame(StackFrame::STUB);
}

// Load deoptimization data from the code object.
// <deopt_data> = <code>[#deoptimization_data_offset]
__ lw(a1, MemOperand(v0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
Expand All @@ -1756,6 +1769,14 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
__ Ret();
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, false);
}

void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, true);
}

// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
Expand Down
27 changes: 24 additions & 3 deletions src/builtins/mips64/builtins-mips64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1718,19 +1718,32 @@ void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kThrowIllegalInvocation);
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
bool has_handler_frame) {
// Lookup the function in the JavaScript frame.
__ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
if (has_handler_frame) {
__ ld(a0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
__ ld(a0, MemOperand(a0, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
}

{
FrameScope scope(masm, StackFrame::INTERNAL);
// Pass function as argument.
__ push(a0);
__ CallRuntime(Runtime::kCompileForOnStackReplacement);
}

// If the code object is null, just return to the unoptimized code.
// If the code object is null, just return to the caller.
__ Ret(eq, v0, Operand(Smi::FromInt(0)));

// Drop any potential handler frame that is be sitting on top of the actual
// JavaScript frame. This is the case then OSR is triggered from bytecode.
if (has_handler_frame) {
__ LeaveFrame(StackFrame::STUB);
}

// Load deoptimization data from the code object.
// <deopt_data> = <code>[#deoptimization_data_offset]
__ ld(a1, MemOperand(v0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
Expand All @@ -1751,6 +1764,14 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
__ Ret();
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, false);
}

void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, true);
}

// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
Expand Down
27 changes: 24 additions & 3 deletions src/builtins/x64/builtins-x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3011,9 +3011,16 @@ void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
}
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
bool has_handler_frame) {
// Lookup the function in the JavaScript frame.
__ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
if (has_handler_frame) {
__ movp(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
__ movp(rax, Operand(rax, JavaScriptFrameConstants::kFunctionOffset));
} else {
__ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
}

{
FrameScope scope(masm, StackFrame::INTERNAL);
// Pass function as argument.
Expand All @@ -3022,13 +3029,19 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
}

Label skip;
// If the code object is null, just return to the unoptimized code.
// If the code object is null, just return to the caller.
__ cmpp(rax, Immediate(0));
__ j(not_equal, &skip, Label::kNear);
__ ret(0);

__ bind(&skip);

// Drop any potential handler frame that is be sitting on top of the actual
// JavaScript frame. This is the case then OSR is triggered from bytecode.
if (has_handler_frame) {
__ leave();
}

// Load deoptimization data from the code object.
__ movp(rbx, Operand(rax, Code::kDeoptimizationDataOffset - kHeapObjectTag));

Expand All @@ -3048,6 +3061,14 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
__ ret(0);
}

void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, false);
}

void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
Generate_OnStackReplacementHelper(masm, true);
}

#undef __

} // namespace internal
Expand Down
6 changes: 6 additions & 0 deletions src/code-factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -601,5 +601,11 @@ Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) {
return Callable(stub.GetCode(), InterpreterCEntryDescriptor(isolate));
}

// static
Callable CodeFactory::InterpreterOnStackReplacement(Isolate* isolate) {
return Callable(isolate->builtins()->InterpreterOnStackReplacement(),
ContextOnlyDescriptor(isolate));
}

} // namespace internal
} // namespace v8
1 change: 1 addition & 0 deletions src/code-factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class CodeFactory final {
CallableType function_type = CallableType::kAny);
static Callable InterpreterPushArgsAndConstruct(Isolate* isolate);
static Callable InterpreterCEntry(Isolate* isolate, int result_size = 1);
static Callable InterpreterOnStackReplacement(Isolate* isolate);
};

} // namespace internal
Expand Down
5 changes: 5 additions & 0 deletions src/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,11 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
Isolate* isolate = function->GetIsolate();
Handle<SharedFunctionInfo> shared(function->shared(), isolate);

// TODO(4764): Remove this guard once OSR graph construction works.
if (!osr_ast_id.IsNone() && osr_frame->is_interpreted()) {
return MaybeHandle<Code>();
}

Handle<Code> cached_code;
if (GetCodeFromOptimizedCodeMap(function, osr_ast_id)
.ToHandle(&cached_code)) {
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/bytecode-graph-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,11 @@ void BytecodeGraphBuilder::VisitStackCheck() {
environment()->RecordAfterState(node, &states);
}

void BytecodeGraphBuilder::VisitOsrPoll() {
// TODO(4764): Implement OSR graph construction. Not marked UNIMPLEMENTED to
// ensure the --ignition-osr flag can already be fuzzed without crashing.
}

void BytecodeGraphBuilder::VisitReturn() {
Node* control =
NewNode(common()->Return(), environment()->LookupAccumulator());
Expand Down
13 changes: 13 additions & 0 deletions src/compiler/code-assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,19 @@ Node* CodeAssembler::CallStubN(Callable const& callable, Node** args,
return CallStubN(callable.descriptor(), target, args, result_size);
}

Node* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, size_t result_size) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);

Node** args = zone()->NewArray<Node*>(1);
args[0] = context;

return CallN(call_descriptor, target, args);
}

Node* CodeAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1,
size_t result_size) {
Expand Down
Loading

0 comments on commit e1ad114

Please sign in to comment.