Revert 3 OSR-related commits

Reason: https://bugs.chromium.org/p/chromium/issues/detail?id=1331309

Reverted commits:

"[compiler] Remove the optimized OSR code if deoptimizing at inside of loop"

https://chromium-review.googlesource.com/c/v8/v8/+/3648219

"[compiler] Add condition use_ic to the removing the optimized OSR code logic"

https://chromium-review.googlesource.com/c/v8/v8/+/3679846

"[compiler] Add out of bytecode array to break condition of removing OSR"

https://chromium-review.googlesource.com/c/v8/v8/+/3686589


Bug: v8:12927, chromium:1330405, chromium:1330452, chromium:1330454, chromium:1330486, chromium:1330545
Change-Id: Idc335e1f6d236a7398b14b64c87da234106bee69
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3687695
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80933}
This commit is contained in:
Marja Hölttä 2022-06-03 10:32:22 +02:00 committed by V8 LUCI CQ
parent 15d117ef7c
commit 9dcdfaec7d

View File

@ -218,95 +218,6 @@ bool DeoptExitIsInsideOsrLoop(Isolate* isolate, JSFunction function,
UNREACHABLE();
}
bool TryGetOptimizedOsrCode(Isolate* isolate, FeedbackVector vector,
const interpreter::BytecodeArrayIterator& it,
CodeT* code_out) {
base::Optional<CodeT> maybe_code =
vector.GetOptimizedOsrCode(isolate, it.GetSlotOperand(2));
if (maybe_code.has_value()) {
*code_out = maybe_code.value();
return true;
}
return false;
}
// Deoptimize all osr'd loops which is in the same outermost loop with deopt
// exit. For example:
// for (;;) {
// for (;;) {
// } // Type a: loop start < OSR backedge < deopt exit
// for (;;) {
// <- Deopt
// for (;;) {
// } // Type b: deopt exit < loop start < OSR backedge
// } // Type c: loop start < deopt exit < OSR backedge
// } // The outermost loop
void DeoptAllOsrLoopsContainingDeoptExit(Isolate* isolate, JSFunction function,
BytecodeOffset deopt_exit_offset) {
DisallowGarbageCollection no_gc;
DCHECK(!deopt_exit_offset.IsNone());
if (!FLAG_use_ic ||
!function.feedback_vector().maybe_has_optimized_osr_code()) {
return;
}
Handle<BytecodeArray> bytecode_array(
function.shared().GetBytecodeArray(isolate), isolate);
DCHECK(interpreter::BytecodeArrayIterator::IsValidOffset(
bytecode_array, deopt_exit_offset.ToInt()));
interpreter::BytecodeArrayIterator it(bytecode_array,
deopt_exit_offset.ToInt());
FeedbackVector vector = function.feedback_vector();
CodeT code;
base::SmallVector<CodeT, 8> osr_codes;
// Visit before the first loop-with-deopt is found
for (; !it.done(); it.Advance()) {
// We're only interested in loop ranges.
if (it.current_bytecode() != interpreter::Bytecode::kJumpLoop) continue;
// Is the deopt exit contained in the current loop?
if (base::IsInRange(deopt_exit_offset.ToInt(), it.GetJumpTargetOffset(),
it.current_offset())) {
break;
}
if (TryGetOptimizedOsrCode(isolate, vector, it, &code)) {
// Collect type b osr'd loops
osr_codes.push_back(code);
}
}
if (it.done()) return;
for (size_t i = 0, size = osr_codes.size(); i < size; i++) {
// Deoptimize type b osr'd loops
osr_codes[i].set_marked_for_deoptimization(true);
}
// Visit after the first loop-with-deopt is found
for (; !it.done(); it.Advance()) {
// We're only interested in loop ranges.
if (it.current_bytecode() != interpreter::Bytecode::kJumpLoop) continue;
if (TryGetOptimizedOsrCode(isolate, vector, it, &code)) {
// Deoptimize type c osr'd loops
code.set_marked_for_deoptimization(true);
}
// We've reached nesting level 0, i.e. the current JumpLoop concludes a
// top-level loop.
const int loop_nesting_level = it.GetImmediateOperand(1);
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());
it.current_offset() < deopt_exit_offset.ToInt(); it.Advance()) {
// We're only interested in loop ranges.
if (it.current_bytecode() != interpreter::Bytecode::kJumpLoop) continue;
if (TryGetOptimizedOsrCode(isolate, vector, it, &code)) {
// Deoptimize type a osr'd loops
code.set_marked_for_deoptimization(true);
}
}
}
} // namespace
RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
@ -347,10 +258,7 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
return ReadOnlyRoots(isolate).undefined_value();
}
// Non-OSR'd code is deoptimized unconditionally. If the deoptimization occurs
// inside the outermost loop containning a loop that can trigger OSR
// compilation, we remove the OSR code, it will avoid hit the out of date OSR
// code and soon later deoptimization.
// Non-OSR'd code is deoptimized unconditionally.
//
// For OSR'd code, we keep the optimized code around if deoptimization occurs
// outside the outermost loop containing the loop that triggered OSR
@ -359,11 +267,9 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
// still worth jumping to the OSR'd code on the next run. The reduced cost of
// the loop should pay for the deoptimization costs.
const BytecodeOffset osr_offset = optimized_code->osr_offset();
if (osr_offset.IsNone()) {
Deoptimizer::DeoptimizeFunction(*function, *optimized_code);
DeoptAllOsrLoopsContainingDeoptExit(isolate, *function, deopt_exit_offset);
} else if (DeoptExitIsInsideOsrLoop(isolate, *function, deopt_exit_offset,
osr_offset)) {
if (osr_offset.IsNone() ||
DeoptExitIsInsideOsrLoop(isolate, *function, deopt_exit_offset,
osr_offset)) {
Deoptimizer::DeoptimizeFunction(*function, *optimized_code);
}