Index: src/runtime/runtime-compiler.cc |
diff --git a/src/runtime/runtime-compiler.cc b/src/runtime/runtime-compiler.cc |
index 258975375cf7dfcff431d4d02fb378bea023ef9f..862fefcd5045ad3fbc7a5dcd85c2b032be34387a 100644 |
--- a/src/runtime/runtime-compiler.cc |
+++ b/src/runtime/runtime-compiler.cc |
@@ -217,38 +217,75 @@ static bool IsSuitableForOnStackReplacement(Isolate* isolate, |
return true; |
} |
+namespace { |
+ |
+BailoutId DetermineEntryAndDisarmOSRForBaseline(JavaScriptFrame* frame) { |
+ Handle<Code> caller_code(frame->function()->shared()->code()); |
+ |
+ // Passing the PC in the JavaScript frame from the caller directly is |
+ // not GC safe, so we walk the stack to get it. |
+ if (!caller_code->contains(frame->pc())) { |
+ // Code on the stack may not be the code object referenced by the shared |
+ // function info. It may have been replaced to include deoptimization data. |
+ caller_code = Handle<Code>(frame->LookupCode()); |
+ } |
+ |
+ DCHECK_EQ(frame->LookupCode(), *caller_code); |
+ DCHECK_EQ(Code::FUNCTION, caller_code->kind()); |
+ DCHECK(caller_code->contains(frame->pc())); |
+ |
+ // Revert the patched back edge table, regardless of whether OSR succeeds. |
+ BackEdgeTable::Revert(frame->isolate(), *caller_code); |
+ |
+ uint32_t pc_offset = |
+ static_cast<uint32_t>(frame->pc() - caller_code->instruction_start()); |
+ |
+ return caller_code->TranslatePcOffsetToAstId(pc_offset); |
+} |
+ |
+BailoutId DetermineEntryAndDisarmOSRForInterpreter(JavaScriptFrame* frame) { |
+ InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame); |
+ |
+ // Note that the bytecode array active on the stack might be different from |
+ // the one installed on the function (e.g. patched by debugger). This however |
+ // is fine because we guarantee the layout to be in sync, hence any BailoutId |
+ // representing the entry point will be valid for any copy of the bytecode. |
+ Handle<BytecodeArray> bytecode(iframe->GetBytecodeArray()); |
+ |
+ DCHECK(frame->LookupCode()->is_interpreter_trampoline_builtin()); |
+ DCHECK(frame->function()->shared()->HasBytecodeArray()); |
+ DCHECK(frame->is_interpreted()); |
+ DCHECK(FLAG_ignition_osr); |
+ |
+ // Reset the OSR loop nesting depth to disarm back edges. |
+ bytecode->set_osr_loop_nesting_level(0); |
+ |
+ return BailoutId(iframe->GetBytecodeOffset()); |
+} |
+ |
+} // namespace |
RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { |
HandleScope scope(isolate); |
DCHECK(args.length() == 1); |
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |
- Handle<Code> caller_code(function->shared()->code()); |
// We're not prepared to handle a function with arguments object. |
DCHECK(!function->shared()->uses_arguments()); |
+ // Only reachable when OST is enabled. |
CHECK(FLAG_use_osr); |
- // Passing the PC in the javascript frame from the caller directly is |
- // not GC safe, so we walk the stack to get it. |
+ // Determine frame triggering OSR request. |
JavaScriptFrameIterator it(isolate); |
JavaScriptFrame* frame = it.frame(); |
- if (!caller_code->contains(frame->pc())) { |
- // Code on the stack may not be the code object referenced by the shared |
- // function info. It may have been replaced to include deoptimization data. |
- caller_code = Handle<Code>(frame->LookupCode()); |
- } |
- |
- uint32_t pc_offset = |
- static_cast<uint32_t>(frame->pc() - caller_code->instruction_start()); |
- |
-#ifdef DEBUG |
DCHECK_EQ(frame->function(), *function); |
- DCHECK_EQ(frame->LookupCode(), *caller_code); |
- DCHECK(caller_code->contains(frame->pc())); |
-#endif // DEBUG |
- BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset); |
+ // Determine the entry point for which this OSR request has been fired and |
+ // also disarm all back edges in the calling code to stop new requests. |
+ BailoutId ast_id = frame->is_interpreted() |
+ ? DetermineEntryAndDisarmOSRForInterpreter(frame) |
+ : DetermineEntryAndDisarmOSRForBaseline(frame); |
DCHECK(!ast_id.IsNone()); |
MaybeHandle<Code> maybe_result; |
@@ -261,9 +298,6 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { |
maybe_result = Compiler::GetOptimizedCodeForOSR(function, ast_id, frame); |
} |
- // Revert the patched back edge table, regardless of whether OSR succeeds. |
- BackEdgeTable::Revert(isolate, *caller_code); |
- |
// Check whether we ended up with usable optimized code. |
Handle<Code> result; |
if (maybe_result.ToHandle(&result) && |