Commit 75b8c238 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[turboprop] Add TURBOPROP code kind

Turboprop-generated Code objects will now have the dedicated
TURBOPROP code kind instead of OPTIMIZED_FUNCTION. When possible,
the code kind is used as the source of truth instead of
FLAG_turboprop. This is the initial step towards implementing
tier-up from Turboprop to Turbofan.

Future work: Rename OPTIMIZED_FUNCTION to TURBOFAN, rename STUB to
DEOPT_ENTRIES_OR_FOR_TESTING, implement TP tier-up.

No-Try: true
Bug: v8:9684
Cq-Include-Trybots: luci.v8.try:v8_linux64_fyi_rel_ng
Change-Id: I3c9308718d7e9a2b7e6796e7ea94f17e5ff84c0a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2424140
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarMythri Alle <mythria@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70213}
parent 83133d95
...@@ -857,8 +857,7 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache( ...@@ -857,8 +857,7 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache(
DCHECK(!code.marked_for_deoptimization()); DCHECK(!code.marked_for_deoptimization());
DCHECK(function->shared().is_compiled()); DCHECK(function->shared().is_compiled());
DCHECK(CodeKindIsStoredInOptimizedCodeCache(code.kind())); DCHECK(CodeKindIsStoredInOptimizedCodeCache(code.kind()));
DCHECK_IMPLIES(!osr_offset.IsNone(), DCHECK_IMPLIES(!osr_offset.IsNone(), CodeKindCanOSR(code.kind()));
code.kind() == CodeKind::OPTIMIZED_FUNCTION);
return Handle<Code>(code, isolate); return Handle<Code>(code, isolate);
} }
return MaybeHandle<Code>(); return MaybeHandle<Code>();
...@@ -902,7 +901,7 @@ void InsertCodeIntoOptimizedCodeCache( ...@@ -902,7 +901,7 @@ void InsertCodeIntoOptimizedCodeCache(
handle(function->feedback_vector(), function->GetIsolate()); handle(function->feedback_vector(), function->GetIsolate());
FeedbackVector::SetOptimizedCode(vector, code); FeedbackVector::SetOptimizedCode(vector, code);
} else { } else {
DCHECK_EQ(kind, CodeKind::OPTIMIZED_FUNCTION); DCHECK(CodeKindCanOSR(kind));
OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code,
compilation_info->osr_offset()); compilation_info->osr_offset());
} }
......
...@@ -85,6 +85,7 @@ void OptimizedCompilationInfo::ConfigureFlags() { ...@@ -85,6 +85,7 @@ void OptimizedCompilationInfo::ConfigureFlags() {
set_function_context_specializing(); set_function_context_specializing();
} }
V8_FALLTHROUGH; V8_FALLTHROUGH;
case CodeKind::TURBOPROP:
case CodeKind::NATIVE_CONTEXT_INDEPENDENT: case CodeKind::NATIVE_CONTEXT_INDEPENDENT:
set_called_with_code_start_register(); set_called_with_code_start_register();
set_switch_jump_table(); set_switch_jump_table();
......
...@@ -429,7 +429,7 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo( ...@@ -429,7 +429,7 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo(
PropertyConstness constness; PropertyConstness constness;
if (details.IsReadOnly() && !details.IsConfigurable()) { if (details.IsReadOnly() && !details.IsConfigurable()) {
constness = PropertyConstness::kConst; constness = PropertyConstness::kConst;
} else if (FLAG_turboprop && !map->is_prototype_map()) { } else if (broker()->is_turboprop() && !map->is_prototype_map()) {
// The constness feedback is too unstable for the aggresive compilation // The constness feedback is too unstable for the aggresive compilation
// of turboprop. // of turboprop.
constness = PropertyConstness::kMutable; constness = PropertyConstness::kMutable;
......
...@@ -4104,7 +4104,7 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -4104,7 +4104,7 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
if (feedback_target.has_value() && feedback_target->map().is_callable()) { if (feedback_target.has_value() && feedback_target->map().is_callable()) {
Node* target_function = jsgraph()->Constant(*feedback_target); Node* target_function = jsgraph()->Constant(*feedback_target);
if (FLAG_turboprop) { if (broker()->is_turboprop()) {
if (!feedback_target->IsJSFunction()) return NoChange(); if (!feedback_target->IsJSFunction()) return NoChange();
if (!IsBuiltinOrApiFunction(feedback_target->AsJSFunction())) { if (!IsBuiltinOrApiFunction(feedback_target->AsJSFunction())) {
return NoChange(); return NoChange();
...@@ -4138,7 +4138,7 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -4138,7 +4138,7 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
return NoChange(); return NoChange();
} }
if (FLAG_turboprop && if (broker()->is_turboprop() &&
!feedback_vector.shared_function_info().HasBuiltinId()) { !feedback_vector.shared_function_info().HasBuiltinId()) {
return NoChange(); return NoChange();
} }
...@@ -4965,7 +4965,7 @@ Reduction JSCallReducer::ReduceForInsufficientFeedback( ...@@ -4965,7 +4965,7 @@ Reduction JSCallReducer::ReduceForInsufficientFeedback(
// TODO(mythria): May be add additional flags to specify if we need to deopt // TODO(mythria): May be add additional flags to specify if we need to deopt
// on calls / construct rather than checking for TurboProp here. We may need // on calls / construct rather than checking for TurboProp here. We may need
// it for NativeContextIndependent code too. // it for NativeContextIndependent code too.
if (FLAG_turboprop) return NoChange(); if (broker()->is_turboprop()) return NoChange();
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
......
...@@ -2390,7 +2390,7 @@ SourceTextModuleRef ContextRef::GetModule(SerializationPolicy policy) const { ...@@ -2390,7 +2390,7 @@ SourceTextModuleRef ContextRef::GetModule(SerializationPolicy policy) const {
JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone, JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone,
bool tracing_enabled, bool is_concurrent_inlining, bool tracing_enabled, bool is_concurrent_inlining,
bool is_native_context_independent) CodeKind code_kind)
: isolate_(isolate), : isolate_(isolate),
zone_(broker_zone), zone_(broker_zone),
refs_(zone()->New<RefsMap>(kMinimalRefsBucketCount, AddressMatcher(), refs_(zone()->New<RefsMap>(kMinimalRefsBucketCount, AddressMatcher(),
...@@ -2399,7 +2399,7 @@ JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone, ...@@ -2399,7 +2399,7 @@ JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone,
array_and_object_prototypes_(zone()), array_and_object_prototypes_(zone()),
tracing_enabled_(tracing_enabled), tracing_enabled_(tracing_enabled),
is_concurrent_inlining_(is_concurrent_inlining), is_concurrent_inlining_(is_concurrent_inlining),
is_native_context_independent_(is_native_context_independent), code_kind_(code_kind),
local_heap_(base::nullopt), local_heap_(base::nullopt),
feedback_(zone()), feedback_(zone()),
bytecode_analyses_(zone()), bytecode_analyses_(zone()),
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "src/handles/persistent-handles.h" #include "src/handles/persistent-handles.h"
#include "src/heap/local-heap.h" #include "src/heap/local-heap.h"
#include "src/interpreter/bytecode-array-accessor.h" #include "src/interpreter/bytecode-array-accessor.h"
#include "src/objects/code-kind.h"
#include "src/objects/feedback-vector.h" #include "src/objects/feedback-vector.h"
#include "src/objects/function-kind.h" #include "src/objects/function-kind.h"
#include "src/objects/objects.h" #include "src/objects/objects.h"
...@@ -78,13 +79,13 @@ struct PropertyAccessTarget { ...@@ -78,13 +79,13 @@ struct PropertyAccessTarget {
class V8_EXPORT_PRIVATE JSHeapBroker { class V8_EXPORT_PRIVATE JSHeapBroker {
public: public:
JSHeapBroker(Isolate* isolate, Zone* broker_zone, bool tracing_enabled, JSHeapBroker(Isolate* isolate, Zone* broker_zone, bool tracing_enabled,
bool is_concurrent_inlining, bool is_native_context_independent); bool is_concurrent_inlining, CodeKind code_kind);
// For use only in tests, sets default values for some arguments. Avoids // For use only in tests, sets default values for some arguments. Avoids
// churn when new flags are added. // churn when new flags are added.
JSHeapBroker(Isolate* isolate, Zone* broker_zone) JSHeapBroker(Isolate* isolate, Zone* broker_zone)
: JSHeapBroker(isolate, broker_zone, FLAG_trace_heap_broker, false, : JSHeapBroker(isolate, broker_zone, FLAG_trace_heap_broker, false,
false) {} CodeKind::OPTIMIZED_FUNCTION) {}
~JSHeapBroker(); ~JSHeapBroker();
...@@ -102,7 +103,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -102,7 +103,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
bool tracing_enabled() const { return tracing_enabled_; } bool tracing_enabled() const { return tracing_enabled_; }
bool is_concurrent_inlining() const { return is_concurrent_inlining_; } bool is_concurrent_inlining() const { return is_concurrent_inlining_; }
bool is_native_context_independent() const { bool is_native_context_independent() const {
return is_native_context_independent_; return code_kind_ == CodeKind::NATIVE_CONTEXT_INDEPENDENT;
} }
bool generate_full_feedback_collection() const { bool generate_full_feedback_collection() const {
// NCI code currently collects full feedback. // NCI code currently collects full feedback.
...@@ -110,6 +111,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -110,6 +111,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
CollectFeedbackInGenericLowering()); CollectFeedbackInGenericLowering());
return is_native_context_independent(); return is_native_context_independent();
} }
bool is_turboprop() const { return code_kind_ == CodeKind::TURBOPROP; }
enum BrokerMode { kDisabled, kSerializing, kSerialized, kRetired }; enum BrokerMode { kDisabled, kSerializing, kSerialized, kRetired };
BrokerMode mode() const { return mode_; } BrokerMode mode() const { return mode_; }
...@@ -357,7 +359,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -357,7 +359,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
BrokerMode mode_ = kDisabled; BrokerMode mode_ = kDisabled;
bool const tracing_enabled_; bool const tracing_enabled_;
bool const is_concurrent_inlining_; bool const is_concurrent_inlining_;
bool const is_native_context_independent_; CodeKind const code_kind_;
std::unique_ptr<PersistentHandles> ph_; std::unique_ptr<PersistentHandles> ph_;
base::Optional<LocalHeap> local_heap_; base::Optional<LocalHeap> local_heap_;
std::unique_ptr<CanonicalHandlesMap> canonical_handles_; std::unique_ptr<CanonicalHandlesMap> canonical_handles_;
......
...@@ -574,8 +574,8 @@ Node* JSTypeHintLowering::TryBuildSoftDeopt(FeedbackSlot slot, Node* effect, ...@@ -574,8 +574,8 @@ Node* JSTypeHintLowering::TryBuildSoftDeopt(FeedbackSlot slot, Node* effect,
FeedbackSource source(feedback_vector(), slot); FeedbackSource source(feedback_vector(), slot);
// TODO(mythria): Think of adding flags to specify if we need a soft deopt for // TODO(mythria): Think of adding flags to specify if we need a soft deopt for
// calls instead of using FLAG_turboprop here. // calls instead of using broker()->is_turboprop() here.
if (FLAG_turboprop && if (broker()->is_turboprop() &&
broker()->GetFeedbackSlotKind(source) == FeedbackSlotKind::kCall) { broker()->GetFeedbackSlotKind(source) == FeedbackSlotKind::kCall) {
return nullptr; return nullptr;
} }
......
...@@ -151,9 +151,9 @@ class PipelineData { ...@@ -151,9 +151,9 @@ class PipelineData {
instruction_zone_(instruction_zone_scope_.zone()), instruction_zone_(instruction_zone_scope_.zone()),
codegen_zone_scope_(zone_stats_, kCodegenZoneName), codegen_zone_scope_(zone_stats_, kCodegenZoneName),
codegen_zone_(codegen_zone_scope_.zone()), codegen_zone_(codegen_zone_scope_.zone()),
broker_(new JSHeapBroker( broker_(new JSHeapBroker(isolate_, info_->zone(),
isolate_, info_->zone(), info_->trace_heap_broker(), info_->trace_heap_broker(),
is_concurrent_inlining, info->IsNativeContextIndependent())), is_concurrent_inlining, info->code_kind())),
register_allocation_zone_scope_(zone_stats_, register_allocation_zone_scope_(zone_stats_,
kRegisterAllocationZoneName), kRegisterAllocationZoneName),
register_allocation_zone_(register_allocation_zone_scope_.zone()), register_allocation_zone_(register_allocation_zone_scope_.zone()),
...@@ -1191,7 +1191,7 @@ PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl( ...@@ -1191,7 +1191,7 @@ PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl(
ParkedScope parked_scope(data_.broker()->local_heap()); ParkedScope parked_scope(data_.broker()->local_heap());
bool success; bool success;
if (FLAG_turboprop) { if (compilation_info_.code_kind() == CodeKind::TURBOPROP) {
success = pipeline_.OptimizeGraphForMidTier(linkage_); success = pipeline_.OptimizeGraphForMidTier(linkage_);
} else { } else {
success = pipeline_.OptimizeGraph(linkage_); success = pipeline_.OptimizeGraph(linkage_);
......
...@@ -1109,7 +1109,8 @@ bool SerializerForBackgroundCompilation::BailoutOnUninitialized( ...@@ -1109,7 +1109,8 @@ bool SerializerForBackgroundCompilation::BailoutOnUninitialized(
// OSR entry point. TODO(neis): Support OSR? // OSR entry point. TODO(neis): Support OSR?
return false; return false;
} }
if (FLAG_turboprop && feedback.slot_kind() == FeedbackSlotKind::kCall) { if (broker()->is_turboprop() &&
feedback.slot_kind() == FeedbackSlotKind::kCall) {
return false; return false;
} }
if (feedback.IsInsufficient()) { if (feedback.IsInsufficient()) {
......
...@@ -205,7 +205,9 @@ void PerfJitLogger::LogRecordedBuffer( ...@@ -205,7 +205,9 @@ void PerfJitLogger::LogRecordedBuffer(
int length) { int length) {
if (FLAG_perf_basic_prof_only_functions && if (FLAG_perf_basic_prof_only_functions &&
(abstract_code->kind() != CodeKind::INTERPRETED_FUNCTION && (abstract_code->kind() != CodeKind::INTERPRETED_FUNCTION &&
abstract_code->kind() != CodeKind::OPTIMIZED_FUNCTION)) { abstract_code->kind() != CodeKind::OPTIMIZED_FUNCTION &&
abstract_code->kind() != CodeKind::NATIVE_CONTEXT_INDEPENDENT &&
abstract_code->kind() != CodeKind::TURBOPROP)) {
return; return;
} }
......
...@@ -591,6 +591,7 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, ...@@ -591,6 +591,7 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
return BUILTIN; return BUILTIN;
case CodeKind::OPTIMIZED_FUNCTION: case CodeKind::OPTIMIZED_FUNCTION:
case CodeKind::NATIVE_CONTEXT_INDEPENDENT: case CodeKind::NATIVE_CONTEXT_INDEPENDENT:
case CodeKind::TURBOPROP:
return OPTIMIZED; return OPTIMIZED;
case CodeKind::JS_TO_WASM_FUNCTION: case CodeKind::JS_TO_WASM_FUNCTION:
return JS_TO_WASM; return JS_TO_WASM;
......
...@@ -240,6 +240,10 @@ OptimizationReason RuntimeProfiler::ShouldOptimize(JSFunction function, ...@@ -240,6 +240,10 @@ OptimizationReason RuntimeProfiler::ShouldOptimize(JSFunction function,
if (function.ActiveTierIsTurbofan()) { if (function.ActiveTierIsTurbofan()) {
return OptimizationReason::kDoNotOptimize; return OptimizationReason::kDoNotOptimize;
} }
if (V8_UNLIKELY(FLAG_turboprop) && function.ActiveTierIsTurboprop()) {
// TODO(turboprop): Implement tier up from Turboprop.
return OptimizationReason::kDoNotOptimize;
}
int ticks = function.feedback_vector().profiler_ticks(); int ticks = function.feedback_vector().profiler_ticks();
int ticks_for_optimization = int ticks_for_optimization =
kProfilerTicksBeforeOptimization + kProfilerTicksBeforeOptimization +
......
...@@ -78,11 +78,13 @@ static v8::CodeEventType GetCodeEventTypeForTag( ...@@ -78,11 +78,13 @@ static v8::CodeEventType GetCodeEventTypeForTag(
} }
static const char* ComputeMarker(SharedFunctionInfo shared, AbstractCode code) { static const char* ComputeMarker(SharedFunctionInfo shared, AbstractCode code) {
// TODO(mythria,jgruber): Use different markers for Turboprop/NCI.
switch (code.kind()) { switch (code.kind()) {
case CodeKind::INTERPRETED_FUNCTION: case CodeKind::INTERPRETED_FUNCTION:
return shared.optimization_disabled() ? "" : "~"; return shared.optimization_disabled() ? "" : "~";
case CodeKind::OPTIMIZED_FUNCTION: case CodeKind::OPTIMIZED_FUNCTION:
case CodeKind::NATIVE_CONTEXT_INDEPENDENT: case CodeKind::NATIVE_CONTEXT_INDEPENDENT:
case CodeKind::TURBOPROP:
return "*"; return "*";
default: default:
return ""; return "";
...@@ -2164,6 +2166,7 @@ void ExistingCodeLogger::LogCodeObject(Object object) { ...@@ -2164,6 +2166,7 @@ void ExistingCodeLogger::LogCodeObject(Object object) {
case CodeKind::INTERPRETED_FUNCTION: case CodeKind::INTERPRETED_FUNCTION:
case CodeKind::OPTIMIZED_FUNCTION: case CodeKind::OPTIMIZED_FUNCTION:
case CodeKind::NATIVE_CONTEXT_INDEPENDENT: case CodeKind::NATIVE_CONTEXT_INDEPENDENT:
case CodeKind::TURBOPROP:
return; // We log this later using LogCompiledFunctions. return; // We log this later using LogCompiledFunctions.
case CodeKind::BYTECODE_HANDLER: case CodeKind::BYTECODE_HANDLER:
return; // We log it later by walking the dispatch table. return; // We log it later by walking the dispatch table.
......
...@@ -28,7 +28,8 @@ namespace internal { ...@@ -28,7 +28,8 @@ namespace internal {
V(JS_TO_JS_FUNCTION) \ V(JS_TO_JS_FUNCTION) \
V(C_WASM_ENTRY) \ V(C_WASM_ENTRY) \
V(INTERPRETED_FUNCTION) \ V(INTERPRETED_FUNCTION) \
V(NATIVE_CONTEXT_INDEPENDENT) V(NATIVE_CONTEXT_INDEPENDENT) \
V(TURBOPROP)
enum class CodeKind { enum class CodeKind {
#define DEFINE_CODE_KIND_ENUM(name) name, #define DEFINE_CODE_KIND_ENUM(name) name,
...@@ -53,7 +54,8 @@ inline constexpr bool CodeKindIsNativeContextIndependentJSFunction( ...@@ -53,7 +54,8 @@ inline constexpr bool CodeKindIsNativeContextIndependentJSFunction(
inline constexpr bool CodeKindIsOptimizedJSFunction(CodeKind kind) { inline constexpr bool CodeKindIsOptimizedJSFunction(CodeKind kind) {
return kind == CodeKind::OPTIMIZED_FUNCTION || return kind == CodeKind::OPTIMIZED_FUNCTION ||
kind == CodeKind::NATIVE_CONTEXT_INDEPENDENT; kind == CodeKind::NATIVE_CONTEXT_INDEPENDENT ||
kind == CodeKind::TURBOPROP;
} }
inline constexpr bool CodeKindIsJSFunction(CodeKind kind) { inline constexpr bool CodeKindIsJSFunction(CodeKind kind) {
...@@ -72,6 +74,10 @@ inline constexpr bool CodeKindCanDeoptimize(CodeKind kind) { ...@@ -72,6 +74,10 @@ inline constexpr bool CodeKindCanDeoptimize(CodeKind kind) {
return CodeKindIsOptimizedJSFunction(kind); return CodeKindIsOptimizedJSFunction(kind);
} }
inline constexpr bool CodeKindCanOSR(CodeKind kind) {
return kind == CodeKind::OPTIMIZED_FUNCTION || kind == CodeKind::TURBOPROP;
}
inline constexpr bool CodeKindChecksOptimizationMarker(CodeKind kind) { inline constexpr bool CodeKindChecksOptimizationMarker(CodeKind kind) {
return kind == CodeKind::INTERPRETED_FUNCTION || return kind == CodeKind::INTERPRETED_FUNCTION ||
kind == CodeKind::NATIVE_CONTEXT_INDEPENDENT; kind == CodeKind::NATIVE_CONTEXT_INDEPENDENT;
...@@ -82,10 +88,13 @@ inline constexpr bool CodeKindChecksOptimizationMarker(CodeKind kind) { ...@@ -82,10 +88,13 @@ inline constexpr bool CodeKindChecksOptimizationMarker(CodeKind kind) {
// access from multiple closures. The marker is not used for all code kinds // access from multiple closures. The marker is not used for all code kinds
// though, in particular it is not used when generating NCI code. // though, in particular it is not used when generating NCI code.
inline constexpr bool CodeKindIsStoredInOptimizedCodeCache(CodeKind kind) { inline constexpr bool CodeKindIsStoredInOptimizedCodeCache(CodeKind kind) {
return kind == CodeKind::OPTIMIZED_FUNCTION; return kind == CodeKind::OPTIMIZED_FUNCTION || kind == CodeKind::TURBOPROP;
} }
inline CodeKind CodeKindForTopTier() { return CodeKind::OPTIMIZED_FUNCTION; } inline CodeKind CodeKindForTopTier() {
return V8_UNLIKELY(FLAG_turboprop) ? CodeKind::TURBOPROP
: CodeKind::OPTIMIZED_FUNCTION;
}
// The dedicated CodeKindFlag enum represents all code kinds in a format // The dedicated CodeKindFlag enum represents all code kinds in a format
// suitable for bit sets. // suitable for bit sets.
...@@ -108,10 +117,10 @@ DEFINE_OPERATORS_FOR_FLAGS(CodeKinds) ...@@ -108,10 +117,10 @@ DEFINE_OPERATORS_FOR_FLAGS(CodeKinds)
static constexpr CodeKinds kJSFunctionCodeKindsMask{ static constexpr CodeKinds kJSFunctionCodeKindsMask{
CodeKindFlag::INTERPRETED_FUNCTION | CodeKindFlag::OPTIMIZED_FUNCTION | CodeKindFlag::INTERPRETED_FUNCTION | CodeKindFlag::OPTIMIZED_FUNCTION |
CodeKindFlag::NATIVE_CONTEXT_INDEPENDENT}; CodeKindFlag::NATIVE_CONTEXT_INDEPENDENT | CodeKindFlag::TURBOPROP};
static constexpr CodeKinds kOptimizedJSFunctionCodeKindsMask{ static constexpr CodeKinds kOptimizedJSFunctionCodeKindsMask{
CodeKindFlag::OPTIMIZED_FUNCTION | CodeKindFlag::OPTIMIZED_FUNCTION |
CodeKindFlag::NATIVE_CONTEXT_INDEPENDENT}; CodeKindFlag::NATIVE_CONTEXT_INDEPENDENT | CodeKindFlag::TURBOPROP};
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -90,6 +90,9 @@ bool HighestTierOf(CodeKinds kinds, CodeKind* highest_tier) { ...@@ -90,6 +90,9 @@ bool HighestTierOf(CodeKinds kinds, CodeKind* highest_tier) {
if ((kinds & CodeKindFlag::OPTIMIZED_FUNCTION) != 0) { if ((kinds & CodeKindFlag::OPTIMIZED_FUNCTION) != 0) {
*highest_tier = CodeKind::OPTIMIZED_FUNCTION; *highest_tier = CodeKind::OPTIMIZED_FUNCTION;
return true; return true;
} else if ((kinds & CodeKindFlag::TURBOPROP) != 0) {
*highest_tier = CodeKind::TURBOPROP;
return true;
} else if ((kinds & CodeKindFlag::NATIVE_CONTEXT_INDEPENDENT) != 0) { } else if ((kinds & CodeKindFlag::NATIVE_CONTEXT_INDEPENDENT) != 0) {
*highest_tier = CodeKind::NATIVE_CONTEXT_INDEPENDENT; *highest_tier = CodeKind::NATIVE_CONTEXT_INDEPENDENT;
return true; return true;
...@@ -128,10 +131,19 @@ bool JSFunction::ActiveTierIsNCI() const { ...@@ -128,10 +131,19 @@ bool JSFunction::ActiveTierIsNCI() const {
return highest_tier == CodeKind::NATIVE_CONTEXT_INDEPENDENT; return highest_tier == CodeKind::NATIVE_CONTEXT_INDEPENDENT;
} }
bool JSFunction::ActiveTierIsTurboprop() const {
CodeKind highest_tier;
if (!HighestTierOf(GetAvailableCodeKinds(), &highest_tier)) return false;
return highest_tier == CodeKind::TURBOPROP;
}
CodeKind JSFunction::NextTier() const { CodeKind JSFunction::NextTier() const {
return (FLAG_turbo_nci_as_midtier && ActiveTierIsIgnition()) if (V8_UNLIKELY(FLAG_turbo_nci_as_midtier && ActiveTierIsIgnition())) {
? CodeKind::NATIVE_CONTEXT_INDEPENDENT return CodeKind::NATIVE_CONTEXT_INDEPENDENT;
: CodeKind::OPTIMIZED_FUNCTION; } else if (V8_UNLIKELY(FLAG_turboprop)) {
return CodeKind::TURBOPROP;
}
return CodeKind::OPTIMIZED_FUNCTION;
} }
bool JSFunction::CanDiscardCompiled() const { bool JSFunction::CanDiscardCompiled() const {
...@@ -144,7 +156,7 @@ bool JSFunction::CanDiscardCompiled() const { ...@@ -144,7 +156,7 @@ bool JSFunction::CanDiscardCompiled() const {
// //
// Note that when the function has not yet been compiled we also return // Note that when the function has not yet been compiled we also return
// false; that's fine, since nothing must be discarded in that case. // false; that's fine, since nothing must be discarded in that case.
if (code().kind() == CodeKind::OPTIMIZED_FUNCTION) return true; if (CodeKindIsOptimizedJSFunction(code().kind())) return true;
CodeKinds result = GetAvailableCodeKinds(); CodeKinds result = GetAvailableCodeKinds();
return (result & kJSFunctionCodeKindsMask) != 0; return (result & kJSFunctionCodeKindsMask) != 0;
} }
......
...@@ -115,6 +115,7 @@ class JSFunction : public JSFunctionOrBoundFunction { ...@@ -115,6 +115,7 @@ class JSFunction : public JSFunctionOrBoundFunction {
V8_EXPORT_PRIVATE bool ActiveTierIsIgnition() const; V8_EXPORT_PRIVATE bool ActiveTierIsIgnition() const;
bool ActiveTierIsTurbofan() const; bool ActiveTierIsTurbofan() const;
bool ActiveTierIsNCI() const; bool ActiveTierIsNCI() const;
bool ActiveTierIsTurboprop() const;
CodeKind NextTier() const; CodeKind NextTier() const;
......
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