From d37910f502a31ac7fda0fbdce8f2672ea04eafe5 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Mon, 27 Jun 2022 20:40:10 +0800 Subject: [PATCH] [compiler] Break removing OSR code cache logic if deopt exit is before a new nesting loop This is probably a JumpLoop to loop nesting level 0 getting removed if it's dead code. Add before a new nesting loop to break condition of removing OSR code cache if deopt at inside of loop. Bug: chromium:1330883 Change-Id: I010e3ca2adaafae8dcc606c49860ca0a70442952 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3713093 Reviewed-by: Leszek Swirski Commit-Queue: Tao Pan Cr-Commit-Position: refs/heads/main@{#81401} --- src/runtime/runtime-compiler.cc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/runtime/runtime-compiler.cc b/src/runtime/runtime-compiler.cc index d8f18c7f1c..e8c0907b15 100644 --- a/src/runtime/runtime-compiler.cc +++ b/src/runtime/runtime-compiler.cc @@ -284,13 +284,23 @@ void DeoptAllOsrLoopsContainingDeoptExit(Isolate* isolate, JSFunction function, } if (it.done()) return; for (size_t i = 0, size = osr_codes.size(); i < size; i++) { - // Deoptimize type b osr'd loops + // Deoptimize type b osr'd loops Deoptimizer::DeoptimizeFunction(function, FromCodeT(osr_codes[i])); } // Visit after the first loop-with-deopt is found + int last_deopt_in_range_loop_jump_target; for (; !it.done(); it.Advance()) { // We're only interested in loop ranges. if (it.current_bytecode() != interpreter::Bytecode::kJumpLoop) continue; + // We've reached a new nesting loop in the case of the deopt exit is in a + // loop whose outermost loop was removed. For example: + // for (;;) { + // <- Deopt + // } // The non-outermost loop + // for (;;) { + // } // The outermost loop + if (it.GetJumpTargetOffset() > deopt_exit_offset.ToInt()) break; + last_deopt_in_range_loop_jump_target = it.GetJumpTargetOffset(); if (TryGetOptimizedOsrCode(isolate, vector, it, &code)) { // Deoptimize type c osr'd loops Deoptimizer::DeoptimizeFunction(function, FromCodeT(code)); @@ -301,9 +311,8 @@ void DeoptAllOsrLoopsContainingDeoptExit(Isolate* isolate, JSFunction function, if (loop_nesting_level == 0) break; } if (it.done()) return; - // Revisit from start of outermost loop to deopt - DCHECK_LE(it.GetJumpTargetOffset(), deopt_exit_offset.ToInt()); - for (it.SetOffset(it.GetJumpTargetOffset()); + // Revisit from start of the last deopt in range loop to deopt + for (it.SetOffset(last_deopt_in_range_loop_jump_target); it.current_offset() < deopt_exit_offset.ToInt(); it.Advance()) { // We're only interested in loop ranges. if (it.current_bytecode() != interpreter::Bytecode::kJumpLoop) continue;