Commit aad3e727 authored by Jakob Gruber's avatar Jakob Gruber Committed by V8 LUCI CQ

Refactor tiering-related JSFunction methods

- Add the Isolate as an explicit param (we already have it at all
  callsites)
- Pass an explicit CodeKind param to MarkForOptimization in preparation
  for Maglev.
- Split EnsureFeedbackVector into that, plus
  CreateAndAttachFeedbackVector for when we know it has to be created.

Bug: v8:7700
Change-Id: Ie9022deccd31d472d6df3d442b25583af5569ab0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3497383
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79318}
parent 6f16737f
......@@ -2029,7 +2029,7 @@ bool Compiler::Compile(Isolate* isolate, Handle<JSFunction> function,
// Install a feedback vector if necessary.
if (code->kind() == CodeKind::BASELINE) {
JSFunction::EnsureFeedbackVector(function, is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate, function, is_compiled_scope);
}
// Check postconditions on success.
......@@ -2103,7 +2103,7 @@ bool Compiler::CompileBaseline(Isolate* isolate, Handle<JSFunction> function,
}
// Baseline code needs a feedback vector.
JSFunction::EnsureFeedbackVector(function, is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate, function, is_compiled_scope);
CodeT baseline_code = shared->baseline_code(kAcquireLoad);
DCHECK_EQ(baseline_code.kind(), CodeKind::BASELINE);
......@@ -2123,7 +2123,7 @@ bool Compiler::CompileMaglev(Isolate* isolate, Handle<JSFunction> function,
DCHECK_EQ(mode, ConcurrencyMode::kNotConcurrent);
// Maglev code needs a feedback vector.
JSFunction::EnsureFeedbackVector(function, is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate, function, is_compiled_scope);
MaybeHandle<CodeT> maybe_code = Maglev::Compile(isolate, function);
Handle<CodeT> code;
......@@ -3395,8 +3395,9 @@ void Compiler::PostInstantiation(Handle<JSFunction> function) {
!shared->optimization_disabled() &&
!function->HasAvailableOptimizedCode()) {
CompilerTracer::TraceMarkForAlwaysOpt(isolate, function);
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
function->MarkForOptimization(ConcurrencyMode::kNotConcurrent);
JSFunction::EnsureFeedbackVector(isolate, function, &is_compiled_scope);
function->MarkForOptimization(isolate, CodeKind::TURBOFAN,
ConcurrencyMode::kNotConcurrent);
}
}
......
......@@ -811,7 +811,7 @@ void Coverage::SelectMode(Isolate* isolate, debug::CoverageMode mode) {
IsCompiledScope is_compiled_scope(
func->shared().is_compiled_scope(isolate));
CHECK(is_compiled_scope.is_compiled());
JSFunction::EnsureFeedbackVector(func, &is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate, func, &is_compiled_scope);
}
// Root all feedback vectors to avoid early collection.
......
......@@ -1081,7 +1081,8 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
if (!js_function->is_compiled()) continue;
IsCompiledScope is_compiled_scope(
js_function->shared().is_compiled_scope(isolate));
JSFunction::EnsureFeedbackVector(js_function, &is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate, js_function,
&is_compiled_scope);
}
if (!sfi->HasBytecodeArray()) continue;
......@@ -1124,7 +1125,8 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
if (!js_function->is_compiled()) continue;
IsCompiledScope is_compiled_scope(
js_function->shared().is_compiled_scope(isolate));
JSFunction::EnsureFeedbackVector(js_function, &is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate, js_function,
&is_compiled_scope);
}
}
SharedFunctionInfo::ScriptIterator it(isolate, *new_script);
......
......@@ -90,7 +90,8 @@ void TieringManager::Optimize(JSFunction function, OptimizationReason reason,
CodeKind code_kind) {
DCHECK_NE(reason, OptimizationReason::kDoNotOptimize);
TraceRecompile(function, reason, code_kind, isolate_);
function.MarkForOptimization(ConcurrencyMode::kConcurrent);
function.MarkForOptimization(isolate_, CodeKind::TURBOFAN,
ConcurrencyMode::kConcurrent);
}
void TieringManager::AttemptOnStackReplacement(UnoptimizedFrame* frame,
......@@ -262,7 +263,8 @@ void TieringManager::OnInterruptTick(Handle<JSFunction> function) {
if (had_feedback_vector) {
function->SetInterruptBudget();
} else {
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
JSFunction::CreateAndAttachFeedbackVector(isolate_, function,
&is_compiled_scope);
DCHECK(is_compiled_scope.is_compiled());
// Also initialize the invocation count here. This is only really needed for
// OSR. When we OSR functions with lazy feedback allocation we want to have
......
......@@ -3935,7 +3935,7 @@ Handle<JSFunction> Factory::JSFunctionBuilder::Build() {
if (code->kind() == CodeKind::BASELINE) {
IsCompiledScope is_compiled_scope(sfi_->is_compiled_scope(isolate_));
JSFunction::EnsureFeedbackVector(result, &is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate_, result, &is_compiled_scope);
}
Compiler::PostInstantiation(result);
......
......@@ -408,10 +408,10 @@ void FeedbackVector::SetOptimizedCode(Handle<FeedbackVector> vector,
}
// static
void FeedbackVector::SetInterruptBudget(FeedbackCell feedback_cell) {
void FeedbackVector::SetInterruptBudget(FeedbackCell feedback_cell, int value) {
DCHECK(feedback_cell.value().IsFeedbackVector());
// Set the interrupt budget as required for tiering up to next level.
feedback_cell.set_interrupt_budget(FLAG_interrupt_budget);
feedback_cell.set_interrupt_budget(value);
}
void FeedbackVector::ClearOptimizedCode() {
......
......@@ -252,10 +252,8 @@ class FeedbackVector
// Clears the optimization marker in the feedback vector.
void ClearOptimizationMarker();
// Sets the interrupt budget based on the optimized code available on the
// feedback vector. This function expects that the feedback cell contains a
// feedback vector.
static void SetInterruptBudget(FeedbackCell feedback_cell);
// This function expects that the feedback cell contains a feedback vector.
static void SetInterruptBudget(FeedbackCell feedback_cell, int value);
// Conversion from a slot to an integer index to the underlying array.
static int GetIndex(FeedbackSlot slot) { return slot.ToInt(); }
......
......@@ -71,7 +71,8 @@ bool JSFunction::IsMarkedForConcurrentOptimization() {
void JSFunction::SetInterruptBudget() {
if (has_feedback_vector()) {
FeedbackVector::SetInterruptBudget(raw_feedback_cell());
int budget = FLAG_interrupt_budget; // For Turbofan.
FeedbackVector::SetInterruptBudget(raw_feedback_cell(), budget);
} else {
DCHECK(shared().is_compiled());
raw_feedback_cell().set_interrupt_budget(
......
......@@ -214,11 +214,6 @@ void JSFunction::MarkForOptimization(Isolate* isolate, CodeKind target_kind,
SetOptimizationMarker(OptimizationMarkerFor(target_kind, mode));
}
void JSFunction::MarkForOptimization(ConcurrencyMode mode) {
Isolate* isolate = GetIsolate();
MarkForOptimization(isolate, CodeKind::TURBOFAN, mode);
}
// static
MaybeHandle<String> JSBoundFunction::GetName(Isolate* isolate,
Handle<JSBoundFunction> function) {
......@@ -342,16 +337,30 @@ void JSFunction::EnsureClosureFeedbackCellArray(
}
// static
void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function,
IsCompiledScope* is_compiled_scope) {
Isolate* const isolate = function->GetIsolate();
DCHECK(is_compiled_scope->is_compiled());
void JSFunction::EnsureFeedbackVector(Isolate* isolate,
Handle<JSFunction> function,
IsCompiledScope* compiled_scope) {
DCHECK(compiled_scope->is_compiled());
DCHECK(function->shared().HasFeedbackMetadata());
if (function->has_feedback_vector()) return;
#if V8_ENABLE_WEBASSEMBLY
if (function->shared().HasAsmWasmData()) return;
#endif // V8_ENABLE_WEBASSEMBLY
CreateAndAttachFeedbackVector(isolate, function, compiled_scope);
}
// static
void JSFunction::CreateAndAttachFeedbackVector(
Isolate* isolate, Handle<JSFunction> function,
IsCompiledScope* compiled_scope) {
DCHECK(compiled_scope->is_compiled());
DCHECK(function->shared().HasFeedbackMetadata());
DCHECK(!function->has_feedback_vector());
#if V8_ENABLE_WEBASSEMBLY
DCHECK(!function->shared().HasAsmWasmData());
#endif // V8_ENABLE_WEBASSEMBLY
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
DCHECK(function->shared().HasBytecodeArray());
......@@ -359,7 +368,7 @@ void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function,
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array =
handle(function->closure_feedback_cell_array(), isolate);
Handle<HeapObject> feedback_vector = FeedbackVector::New(
isolate, shared, closure_feedback_cell_array, is_compiled_scope);
isolate, shared, closure_feedback_cell_array, compiled_scope);
// EnsureClosureFeedbackCellArray should handle the special case where we need
// to allocate a new feedback cell. Please look at comment in that function
// for more details.
......@@ -403,7 +412,7 @@ void JSFunction::InitializeFeedbackCell(
isolate->is_collecting_type_profile();
if (needs_feedback_vector) {
EnsureFeedbackVector(function, is_compiled_scope);
CreateAndAttachFeedbackVector(isolate, function, is_compiled_scope);
} else {
EnsureClosureFeedbackCellArray(function,
reset_budget_for_feedback_allocation);
......
......@@ -163,8 +163,6 @@ class JSFunction : public TorqueGeneratedJSFunction<
// the next time it is executed.
void MarkForOptimization(Isolate* isolate, CodeKind target_kind,
ConcurrencyMode mode);
// TODO(v8:7700): Remove this function and pass the CodeKind explicitly.
void MarkForOptimization(ConcurrencyMode mode);
// Tells whether or not the function is already marked for lazy recompilation.
inline bool IsMarkedForOptimization();
......@@ -208,7 +206,11 @@ class JSFunction : public TorqueGeneratedJSFunction<
inline FeedbackVector feedback_vector() const;
inline bool has_feedback_vector() const;
V8_EXPORT_PRIVATE static void EnsureFeedbackVector(
Handle<JSFunction> function, IsCompiledScope* compiled_scope);
Isolate* isolate, Handle<JSFunction> function,
IsCompiledScope* compiled_scope);
static void CreateAndAttachFeedbackVector(Isolate* isolate,
Handle<JSFunction> function,
IsCompiledScope* compiled_scope);
// Functions related to closure feedback cell array that holds feedback cells
// used to create closures from this function. We allocate closure feedback
......
......@@ -86,7 +86,8 @@ RUNTIME_FUNCTION(Runtime_InstallBaselineCode) {
DCHECK(!function->HasAvailableOptimizedCode());
DCHECK(!function->HasOptimizationMarker());
DCHECK(!function->has_feedback_vector());
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
JSFunction::CreateAndAttachFeedbackVector(isolate, function,
&is_compiled_scope);
CodeT baseline_code = sfi->baseline_code(kAcquireLoad);
function->set_code(baseline_code);
return baseline_code;
......
......@@ -333,8 +333,8 @@ Object OptimizeFunctionOnNextCall(RuntimeArguments& args, Isolate* isolate) {
function->set_code(codet);
}
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
function->MarkForOptimization(concurrency_mode);
JSFunction::EnsureFeedbackVector(isolate, function, &is_compiled_scope);
function->MarkForOptimization(isolate, CodeKind::TURBOFAN, concurrency_mode);
return ReadOnlyRoots(isolate).undefined_value();
}
......@@ -362,7 +362,7 @@ bool EnsureFeedbackVector(Isolate* isolate, Handle<JSFunction> function) {
// Ensure function has a feedback vector to hold type feedback for
// optimization.
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate, function, &is_compiled_scope);
return true;
}
......@@ -457,7 +457,7 @@ RUNTIME_FUNCTION(Runtime_OptimizeMaglevOnNextCall) {
CodeKindToString(kCodeKind));
}
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate, function, &is_compiled_scope);
function->MarkForOptimization(isolate, kCodeKind, concurrency_mode);
return ReadOnlyRoots(isolate).undefined_value();
......@@ -581,8 +581,9 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
}
IsCompiledScope is_compiled_scope(
function->shared().is_compiled_scope(isolate));
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
function->MarkForOptimization(ConcurrencyMode::kNotConcurrent);
JSFunction::EnsureFeedbackVector(isolate, function, &is_compiled_scope);
function->MarkForOptimization(isolate, CodeKind::TURBOFAN,
ConcurrencyMode::kNotConcurrent);
// Make the profiler arm all back edges in unoptimized code.
if (it.frame()->is_unoptimized()) {
......
......@@ -279,7 +279,7 @@ i::Handle<i::JSFunction> Optimize(
}
CHECK(info.shared_info()->HasBytecodeArray());
i::JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
i::JSFunction::EnsureFeedbackVector(isolate, function, &is_compiled_scope);
i::Handle<i::CodeT> code = i::ToCodeT(
i::compiler::Pipeline::GenerateCodeForTesting(&info, isolate, out_broker)
......
......@@ -119,7 +119,7 @@ TEST(TestConcurrentSharedFunctionInfo) {
Handle<SharedFunctionInfo> test_sfi(test->shared(), isolate);
DCHECK(test_sfi->HasBytecodeArray());
IsCompiledScope compiled_scope_test(*test_sfi, isolate);
JSFunction::EnsureFeedbackVector(test, &compiled_scope_test);
JSFunction::EnsureFeedbackVector(isolate, test, &compiled_scope_test);
// Get function "f"
Local<Function> function_f = Local<Function>::Cast(
......@@ -135,7 +135,7 @@ TEST(TestConcurrentSharedFunctionInfo) {
Pipeline::GenerateCodeForTesting(&f_info, isolate).ToHandleChecked();
f->set_code(*f_code, kReleaseStore);
IsCompiledScope compiled_scope_f(*f_sfi, isolate);
JSFunction::EnsureFeedbackVector(f, &compiled_scope_f);
JSFunction::EnsureFeedbackVector(isolate, f, &compiled_scope_f);
ExpectSharedFunctionInfoState(*test_sfi, SfiState::Compiled);
......
......@@ -120,7 +120,7 @@ class BytecodeGraphTester {
Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
IsCompiledScope is_compiled_scope(
function->shared().is_compiled_scope(isolate_));
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate_, function, &is_compiled_scope);
CHECK(function->shared().HasBytecodeArray());
Zone zone(isolate_->allocator(), ZONE_NAME);
......
......@@ -1222,7 +1222,7 @@ HEAP_TEST(Regress10560) {
// Allocate feedback vector.
IsCompiledScope is_compiled_scope(
function->shared().is_compiled_scope(i_isolate));
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
JSFunction::EnsureFeedbackVector(i_isolate, function, &is_compiled_scope);
CHECK(function->has_feedback_vector());
CHECK(function->shared().is_compiled());
......
......@@ -164,7 +164,7 @@ class InterpreterTester {
// overwriting existing metadata.
function->shared().set_raw_outer_scope_info_or_feedback_metadata(
*feedback_metadata_.ToHandleChecked());
JSFunction::EnsureFeedbackVector(function, &is_compiled_scope);
JSFunction::EnsureFeedbackVector(isolate_, function, &is_compiled_scope);
}
return function;
}
......
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