97ae101029
Allocating a new feedback vector happens in two steps: We create an empty structure and then initialize the array based on the FeedbackMetadata.When allocating a new feedback array we could trigger a GC which might flush the bytecode and associated feedback metadata. This shouldn't happen in normal cases, because we either allocate feedback vector after compilation or when we reach the expected budget. In both cases, the age of the feedback vector should be 0 and hence bytecode shouldn't be flushed. However, with debugger enabled we may allocate feedback vectors even when the bytecode array is old for example: when we enable precise invocation counters. This also causes issues in tests with --stress-flush-bytecode. In the stress mode we flush bytecode without considering the age. Holding on to the feedback metadata prevents crashes in such cases. Bug: v8:10560 Change-Id: Ie806ff4102cb5fcf257c8683d5ca957853e38c05 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2218066 Commit-Queue: Mythri Alle <mythria@chromium.org> Auto-Submit: Mythri Alle <mythria@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#68052}
35 lines
1.1 KiB
JavaScript
35 lines
1.1 KiB
JavaScript
// Copyright 2017 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --allow-natives-syntax
|
|
|
|
function f() {
|
|
function g(arg) { return arg; }
|
|
// The closure contains a call IC slot.
|
|
return function() { return g(42); };
|
|
}
|
|
|
|
const a = Realm.create();
|
|
const b = Realm.create();
|
|
|
|
// Create two closures in different contexts sharing the same
|
|
// SharedFunctionInfo (shared due to code caching).
|
|
const x = Realm.eval(a, f.toString() + " f()");
|
|
const y = Realm.eval(b, f.toString() + " f()");
|
|
|
|
// Run the first closure to create SFI::code.
|
|
x();
|
|
|
|
// At this point, SFI::code is set and `x` has a feedback vector (`y` does not).
|
|
|
|
// Enabling block code coverage deoptimizes all functions and triggers the
|
|
// buggy code path in which we'd unconditionally replace JSFunction::code with
|
|
// its SFI::code (but skip feedback vector setup).
|
|
%DebugToggleBlockCoverage(true);
|
|
|
|
// Still no feedback vector set on `y` but it now contains code. Run it to
|
|
// trigger the crash when attempting to write into the non-existent feedback
|
|
// vector.
|
|
y();
|