[coverage] Do not reset JSFunction::code post-deoptimization
When enabling any coverage mode (other than best-effort), we trigger deoptimization of all functions on the heap. Prior to the recent removal of the weak list of optimized functions [0], we'd unlink optimized code from all relevant JSFunctions during the call to DeoptimizeAll. After the weak-list-removal, this was no longer the case, hence this [1] change which attempts to reset the code object from the SharedFunctionInfo for all found JSFunction objects. But this can create a situation in which JSFunctions are set up incorrectly s.t. they have unoptimized code but no feedback vector. This CL fixes that by leaving JSFunction objects untouched and relying on self-healing mechanisms (CompileLazyDeoptimizedCode) to fix up JSFunction::code. [0] https://crrev.com/f0acede9bb05155c25ee87e81b4b587e8a76f690 [1] https://crrev.com/c/647596/5/src/debug/debug-coverage.cc Bug: chromium:786784, chromium:791940, v8:6637 Change-Id: I13191f4c8800a0d72894b959105189dc09ca693e Reviewed-on: https://chromium-review.googlesource.com/813615 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#49932}
This commit is contained in:
parent
82508b7158
commit
8303dc531b
@ -3196,9 +3196,6 @@ void Isolate::InitializeVectorListFromHeap() {
|
||||
if (!shared->IsSubjectToDebugging()) continue;
|
||||
vector->clear_invocation_count();
|
||||
vectors.emplace_back(vector, this);
|
||||
} else if (current_obj->IsJSFunction()) {
|
||||
JSFunction* function = JSFunction::cast(current_obj);
|
||||
function->set_code(function->shared()->code());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
34
test/mjsunit/regress/regress-786784.js
Normal file
34
test/mjsunit/regress/regress-786784.js
Normal file
@ -0,0 +1,34 @@
|
||||
// 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();
|
Loading…
Reference in New Issue
Block a user