blob: 9e33de7918cda2fc158c609e701a13f041ea7735 [file] [log] [blame]
// Copyright 2019 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.
#include "src/codegen/pending-optimization-table.h"
#include "src/execution/isolate-inl.h"
#include "src/heap/heap-inl.h"
#include "src/objects/hash-table.h"
#include "src/objects/js-objects.h"
namespace v8 {
namespace internal {
enum class FunctionStatus { kPrepareForOptimize, kMarkForOptimize };
void PendingOptimizationTable::PreparedForOptimization(
Isolate* isolate, Handle<JSFunction> function) {
DCHECK(FLAG_testing_d8_test_runner);
Handle<ObjectHashTable> table =
isolate->heap()->pending_optimize_for_test_bytecode().IsUndefined()
? ObjectHashTable::New(isolate, 1)
: handle(ObjectHashTable::cast(
isolate->heap()->pending_optimize_for_test_bytecode()),
isolate);
Handle<Tuple2> tuple = isolate->factory()->NewTuple2(
handle(function->shared().GetBytecodeArray(), isolate),
handle(
Smi::FromInt(static_cast<int>(FunctionStatus::kPrepareForOptimize)),
isolate),
AllocationType::kYoung);
table =
ObjectHashTable::Put(table, handle(function->shared(), isolate), tuple);
isolate->heap()->SetPendingOptimizeForTestBytecode(*table);
}
void PendingOptimizationTable::MarkedForOptimization(
Isolate* isolate, Handle<JSFunction> function) {
DCHECK(FLAG_testing_d8_test_runner);
Handle<Object> table =
handle(isolate->heap()->pending_optimize_for_test_bytecode(), isolate);
Handle<Object> entry =
table->IsUndefined()
? handle(ReadOnlyRoots(isolate).the_hole_value(), isolate)
: handle(Handle<ObjectHashTable>::cast(table)->Lookup(
handle(function->shared(), isolate)),
isolate);
if (entry->IsTheHole()) {
PrintF("Error: Function ");
function->ShortPrint();
PrintF(
" should be prepared for optimization with "
"%%PrepareFunctionForOptimize before "
"%%OptimizeFunctionOnNextCall / %%OptimizeOSR ");
UNREACHABLE();
}
DCHECK(entry->IsTuple2());
Handle<Tuple2>::cast(entry)->set_value2(
Smi::FromInt(static_cast<int>(FunctionStatus::kMarkForOptimize)));
table = ObjectHashTable::Put(Handle<ObjectHashTable>::cast(table),
handle(function->shared(), isolate), entry);
isolate->heap()->SetPendingOptimizeForTestBytecode(*table);
}
void PendingOptimizationTable::FunctionWasOptimized(
Isolate* isolate, Handle<JSFunction> function) {
DCHECK(FLAG_testing_d8_test_runner);
if (isolate->heap()->pending_optimize_for_test_bytecode().IsUndefined()) {
return;
}
Handle<ObjectHashTable> table =
handle(ObjectHashTable::cast(
isolate->heap()->pending_optimize_for_test_bytecode()),
isolate);
Handle<Object> value(table->Lookup(handle(function->shared(), isolate)),
isolate);
// Remove only if we have already seen %OptimizeFunctionOnNextCall. If it is
// optimized for other reasons, still keep holding the bytecode since we may
// optimize it later.
if (!value->IsTheHole() &&
Smi::cast(Handle<Tuple2>::cast(value)->value2()).value() ==
static_cast<int>(FunctionStatus::kMarkForOptimize)) {
bool was_present;
table = table->Remove(isolate, table, handle(function->shared(), isolate),
&was_present);
DCHECK(was_present);
isolate->heap()->SetPendingOptimizeForTestBytecode(*table);
}
}
} // namespace internal
} // namespace v8