• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_OBJECTS_CODE_KIND_H_
6 #define V8_OBJECTS_CODE_KIND_H_
7 
8 #include "src/base/flags.h"
9 #include "src/flags/flags.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 // The order of INTERPRETED_FUNCTION to TURBOFAN is important. We use it to
15 // check the relative ordering of the tiers when fetching / installing optimized
16 // code.
17 #define CODE_KIND_LIST(V)       \
18   V(BYTECODE_HANDLER)           \
19   V(FOR_TESTING)                \
20   V(BUILTIN)                    \
21   V(REGEXP)                     \
22   V(WASM_FUNCTION)              \
23   V(WASM_TO_CAPI_FUNCTION)      \
24   V(WASM_TO_JS_FUNCTION)        \
25   V(JS_TO_WASM_FUNCTION)        \
26   V(JS_TO_JS_FUNCTION)          \
27   V(C_WASM_ENTRY)               \
28   V(INTERPRETED_FUNCTION)       \
29   V(NATIVE_CONTEXT_INDEPENDENT) \
30   V(TURBOPROP)                  \
31   V(TURBOFAN)
32 
33 enum class CodeKind {
34 #define DEFINE_CODE_KIND_ENUM(name) name,
35   CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
36 #undef DEFINE_CODE_KIND_ENUM
37 };
38 STATIC_ASSERT(CodeKind::INTERPRETED_FUNCTION < CodeKind::TURBOPROP &&
39               CodeKind::INTERPRETED_FUNCTION <
40                   CodeKind::NATIVE_CONTEXT_INDEPENDENT);
41 STATIC_ASSERT(CodeKind::TURBOPROP < CodeKind::TURBOFAN &&
42               CodeKind::NATIVE_CONTEXT_INDEPENDENT < CodeKind::TURBOFAN);
43 
44 #define V(...) +1
45 static constexpr int kCodeKindCount = CODE_KIND_LIST(V);
46 #undef V
47 
48 const char* CodeKindToString(CodeKind kind);
49 
CodeKindIsInterpretedJSFunction(CodeKind kind)50 inline constexpr bool CodeKindIsInterpretedJSFunction(CodeKind kind) {
51   return kind == CodeKind::INTERPRETED_FUNCTION;
52 }
53 
CodeKindIsNativeContextIndependentJSFunction(CodeKind kind)54 inline constexpr bool CodeKindIsNativeContextIndependentJSFunction(
55     CodeKind kind) {
56   return kind == CodeKind::NATIVE_CONTEXT_INDEPENDENT;
57 }
58 
CodeKindIsOptimizedJSFunction(CodeKind kind)59 inline constexpr bool CodeKindIsOptimizedJSFunction(CodeKind kind) {
60   return kind == CodeKind::TURBOFAN ||
61          kind == CodeKind::NATIVE_CONTEXT_INDEPENDENT ||
62          kind == CodeKind::TURBOPROP;
63 }
64 
CodeKindIsJSFunction(CodeKind kind)65 inline constexpr bool CodeKindIsJSFunction(CodeKind kind) {
66   return kind == CodeKind::INTERPRETED_FUNCTION ||
67          CodeKindIsOptimizedJSFunction(kind);
68 }
69 
CodeKindIsBuiltinOrJSFunction(CodeKind kind)70 inline constexpr bool CodeKindIsBuiltinOrJSFunction(CodeKind kind) {
71   return kind == CodeKind::BUILTIN || CodeKindIsJSFunction(kind);
72 }
73 
CodeKindCanDeoptimize(CodeKind kind)74 inline constexpr bool CodeKindCanDeoptimize(CodeKind kind) {
75   // Even though NCI code does not deopt by itself at the time of writing,
76   // tests may trigger deopts manually and thus we cannot make a narrower
77   // distinction here.
78   return CodeKindIsOptimizedJSFunction(kind);
79 }
80 
CodeKindCanOSR(CodeKind kind)81 inline constexpr bool CodeKindCanOSR(CodeKind kind) {
82   return kind == CodeKind::TURBOFAN || kind == CodeKind::TURBOPROP;
83 }
84 
CodeKindIsOptimizedAndCanTierUp(CodeKind kind)85 inline constexpr bool CodeKindIsOptimizedAndCanTierUp(CodeKind kind) {
86   return kind == CodeKind::NATIVE_CONTEXT_INDEPENDENT ||
87          (FLAG_turboprop_as_midtier && kind == CodeKind::TURBOPROP);
88 }
89 
CodeKindCanTierUp(CodeKind kind)90 inline constexpr bool CodeKindCanTierUp(CodeKind kind) {
91   return kind == CodeKind::INTERPRETED_FUNCTION ||
92          CodeKindIsOptimizedAndCanTierUp(kind);
93 }
94 
95 // The optimization marker field on the feedback vector has a dual purpose of
96 // controlling the tier-up workflow, and caching the produced code object for
97 // access from multiple closures. The marker is not used for all code kinds
98 // though, in particular it is not used when generating NCI code.
CodeKindIsStoredInOptimizedCodeCache(CodeKind kind)99 inline constexpr bool CodeKindIsStoredInOptimizedCodeCache(CodeKind kind) {
100   return kind == CodeKind::TURBOFAN || kind == CodeKind::TURBOPROP;
101 }
102 
GetTierForCodeKind(CodeKind kind)103 inline OptimizationTier GetTierForCodeKind(CodeKind kind) {
104   if (kind == CodeKind::TURBOFAN) return OptimizationTier::kTopTier;
105   if (kind == CodeKind::TURBOPROP) {
106     return FLAG_turboprop_as_midtier ? OptimizationTier::kMidTier
107                                      : OptimizationTier::kTopTier;
108   }
109   if (kind == CodeKind::NATIVE_CONTEXT_INDEPENDENT) {
110     return FLAG_turbo_nci_as_midtier ? OptimizationTier::kMidTier
111                                      : OptimizationTier::kTopTier;
112   }
113   return OptimizationTier::kNone;
114 }
115 
CodeKindForTopTier()116 inline CodeKind CodeKindForTopTier() {
117   // TODO(turboprop, mythria): We should make FLAG_turboprop mean turboprop is
118   // mid-tier compiler and replace FLAG_turboprop_as_midtier with
119   // FLAG_turboprop_as_top_tier to tier up to only Turboprop once
120   // FLAG_turboprop_as_midtier is stable and major regressions are addressed.
121   if (V8_UNLIKELY(FLAG_turboprop)) {
122     return FLAG_turboprop_as_midtier ? CodeKind::TURBOFAN : CodeKind::TURBOPROP;
123   }
124   return CodeKind::TURBOFAN;
125 }
126 
127 // The dedicated CodeKindFlag enum represents all code kinds in a format
128 // suitable for bit sets.
129 enum class CodeKindFlag {
130 #define V(name) name = 1 << static_cast<int>(CodeKind::name),
131   CODE_KIND_LIST(V)
132 #undef V
133 };
134 STATIC_ASSERT(kCodeKindCount <= kInt32Size * kBitsPerByte);
135 
CodeKindToCodeKindFlag(CodeKind kind)136 inline constexpr CodeKindFlag CodeKindToCodeKindFlag(CodeKind kind) {
137 #define V(name) kind == CodeKind::name ? CodeKindFlag::name:
138   return CODE_KIND_LIST(V) CodeKindFlag::INTERPRETED_FUNCTION;
139 #undef V
140 }
141 
142 // CodeKinds represents a set of CodeKind.
143 using CodeKinds = base::Flags<CodeKindFlag>;
DEFINE_OPERATORS_FOR_FLAGS(CodeKinds)144 DEFINE_OPERATORS_FOR_FLAGS(CodeKinds)
145 
146 static constexpr CodeKinds kJSFunctionCodeKindsMask{
147     CodeKindFlag::INTERPRETED_FUNCTION | CodeKindFlag::TURBOFAN |
148     CodeKindFlag::NATIVE_CONTEXT_INDEPENDENT | CodeKindFlag::TURBOPROP};
149 static constexpr CodeKinds kOptimizedJSFunctionCodeKindsMask{
150     CodeKindFlag::TURBOFAN | CodeKindFlag::NATIVE_CONTEXT_INDEPENDENT |
151     CodeKindFlag::TURBOPROP};
152 
153 }  // namespace internal
154 }  // namespace v8
155 
156 #endif  // V8_OBJECTS_CODE_KIND_H_
157