Commit 329ac1f8 authored by Mythri A's avatar Mythri A Committed by Commit Bot

[Compile] Hold multiple bytecode-arrays to avoid flushing when optimizing in tests

We added %PrepareForOptimization, that holds the bytecode array strongly until the
function is optimized, to test using assertOptimized. This function expects that the
function is optimized before preparing the next function for optimization. In some
tests, we may not explicitly optimize a function because it got inlined into other
functions or if it was already optimized. This cl relaxes this condition and holds
onto multiple bytecode arrays.

Bug: v8:8801, v8:8395
Change-Id: Iebccc4a798aa3f35be9ee295eb3c4917da659c22
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1541055Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Mythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60552}
parent 13730cee
...@@ -756,10 +756,15 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, ...@@ -756,10 +756,15 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
// If code was pending optimization for testing, delete remove the strong root // If code was pending optimization for testing, delete remove the strong root
// that was preventing the bytecode from being flushed between marking and // that was preventing the bytecode from being flushed between marking and
// optimization. // optimization.
if (isolate->heap()->pending_optimize_for_test_bytecode() == if (!isolate->heap()->pending_optimize_for_test_bytecode()->IsUndefined()) {
shared->GetBytecodeArray()) { Handle<ObjectHashTable> table =
isolate->heap()->SetPendingOptimizeForTestBytecode( handle(ObjectHashTable::cast(
ReadOnlyRoots(isolate).undefined_value()); isolate->heap()->pending_optimize_for_test_bytecode()),
isolate);
bool was_present;
table = table->Remove(isolate, table, handle(function->shared(), isolate),
&was_present);
isolate->heap()->SetPendingOptimizeForTestBytecode(*table);
} }
Handle<Code> cached_code; Handle<Code> cached_code;
......
...@@ -119,9 +119,9 @@ void Heap::SetMessageListeners(TemplateList value) { ...@@ -119,9 +119,9 @@ void Heap::SetMessageListeners(TemplateList value) {
roots_table()[RootIndex::kMessageListeners] = value->ptr(); roots_table()[RootIndex::kMessageListeners] = value->ptr();
} }
void Heap::SetPendingOptimizeForTestBytecode(Object bytecode) { void Heap::SetPendingOptimizeForTestBytecode(Object hash_table) {
DCHECK(bytecode->IsBytecodeArray() || bytecode->IsUndefined(isolate())); DCHECK(hash_table->IsObjectHashTable() || hash_table->IsUndefined(isolate()));
roots_table()[RootIndex::kPendingOptimizeForTestBytecode] = bytecode->ptr(); roots_table()[RootIndex::kPendingOptimizeForTestBytecode] = hash_table->ptr();
} }
PagedSpace* Heap::paged_space(int idx) { PagedSpace* Heap::paged_space(int idx) {
......
...@@ -233,6 +233,15 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) { ...@@ -233,6 +233,15 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
} }
Handle<JSFunction> function = Handle<JSFunction>::cast(function_object); Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
// Check we called PrepareFunctionForOptimization and hold the bytecode
// array to prevent it from getting flushed.
// TODO(mythria): Enable this check once we add PrepareForOptimization in all
// tests before calling OptimizeFunctionOnNextCall.
// CHECK(!ObjectHashTable::cast(
// isolate->heap()->pending_optimize_for_test_bytecode())
// ->Lookup(handle(function->shared(), isolate))
// ->IsTheHole());
// The following conditions were lifted (in part) from the DCHECK inside // The following conditions were lifted (in part) from the DCHECK inside
// JSFunction::MarkForOptimization(). // JSFunction::MarkForOptimization().
...@@ -337,9 +346,6 @@ RUNTIME_FUNCTION(Runtime_PrepareFunctionForOptimization) { ...@@ -337,9 +346,6 @@ RUNTIME_FUNCTION(Runtime_PrepareFunctionForOptimization) {
DCHECK_EQ(1, args.length()); DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
// Only one function should be prepared for optimization at a time
CHECK(isolate->heap()->pending_optimize_for_test_bytecode()->IsUndefined());
if (!EnsureFeedbackVector(function)) { if (!EnsureFeedbackVector(function)) {
return ReadOnlyRoots(isolate).undefined_value(); return ReadOnlyRoots(isolate).undefined_value();
} }
...@@ -367,8 +373,16 @@ RUNTIME_FUNCTION(Runtime_PrepareFunctionForOptimization) { ...@@ -367,8 +373,16 @@ RUNTIME_FUNCTION(Runtime_PrepareFunctionForOptimization) {
// Hold onto the bytecode array between marking and optimization to ensure // Hold onto the bytecode array between marking and optimization to ensure
// it's not flushed. // it's not flushed.
isolate->heap()->SetPendingOptimizeForTestBytecode( Handle<ObjectHashTable> table =
function->shared()->GetBytecodeArray()); isolate->heap()->pending_optimize_for_test_bytecode()->IsUndefined()
? ObjectHashTable::New(isolate, 1)
: handle(ObjectHashTable::cast(
isolate->heap()->pending_optimize_for_test_bytecode()),
isolate);
table = ObjectHashTable::Put(
table, handle(function->shared(), isolate),
handle(function->shared()->GetBytecodeArray(), isolate));
isolate->heap()->SetPendingOptimizeForTestBytecode(*table);
return ReadOnlyRoots(isolate).undefined_value(); return ReadOnlyRoots(isolate).undefined_value();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment