• 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/bounds.h"
9 #include "src/base/flags.h"
10 #include "src/flags/flags.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 // The order of INTERPRETED_FUNCTION to TURBOFAN is important. We use it to
16 // check the relative ordering of the tiers when fetching / installing optimized
17 // code.
18 #define CODE_KIND_LIST(V)  \
19   V(BYTECODE_HANDLER)      \
20   V(FOR_TESTING)           \
21   V(BUILTIN)               \
22   V(REGEXP)                \
23   V(WASM_FUNCTION)         \
24   V(WASM_TO_CAPI_FUNCTION) \
25   V(WASM_TO_JS_FUNCTION)   \
26   V(JS_TO_WASM_FUNCTION)   \
27   V(JS_TO_JS_FUNCTION)     \
28   V(C_WASM_ENTRY)          \
29   V(INTERPRETED_FUNCTION)  \
30   V(BASELINE)              \
31   V(MAGLEV)                \
32   V(TURBOFAN)
33 
34 enum class CodeKind : uint8_t {
35 #define DEFINE_CODE_KIND_ENUM(name) name,
36   CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
37 #undef DEFINE_CODE_KIND_ENUM
38 };
39 STATIC_ASSERT(CodeKind::INTERPRETED_FUNCTION < CodeKind::BASELINE);
40 STATIC_ASSERT(CodeKind::BASELINE < CodeKind::TURBOFAN);
41 
42 #define V(...) +1
43 static constexpr int kCodeKindCount = CODE_KIND_LIST(V);
44 #undef V
45 // Unlikely, but just to be safe:
46 STATIC_ASSERT(kCodeKindCount <= std::numeric_limits<uint8_t>::max());
47 
48 const char* CodeKindToString(CodeKind kind);
49 
50 const char* CodeKindToMarker(CodeKind kind);
51 
CodeKindIsInterpretedJSFunction(CodeKind kind)52 inline constexpr bool CodeKindIsInterpretedJSFunction(CodeKind kind) {
53   return kind == CodeKind::INTERPRETED_FUNCTION;
54 }
55 
CodeKindIsBaselinedJSFunction(CodeKind kind)56 inline constexpr bool CodeKindIsBaselinedJSFunction(CodeKind kind) {
57   return kind == CodeKind::BASELINE;
58 }
59 
CodeKindIsUnoptimizedJSFunction(CodeKind kind)60 inline constexpr bool CodeKindIsUnoptimizedJSFunction(CodeKind kind) {
61   STATIC_ASSERT(static_cast<int>(CodeKind::INTERPRETED_FUNCTION) + 1 ==
62                 static_cast<int>(CodeKind::BASELINE));
63   return base::IsInRange(kind, CodeKind::INTERPRETED_FUNCTION,
64                          CodeKind::BASELINE);
65 }
66 
CodeKindIsOptimizedJSFunction(CodeKind kind)67 inline constexpr bool CodeKindIsOptimizedJSFunction(CodeKind kind) {
68   STATIC_ASSERT(static_cast<int>(CodeKind::MAGLEV) + 1 ==
69                 static_cast<int>(CodeKind::TURBOFAN));
70   return base::IsInRange(kind, CodeKind::MAGLEV, CodeKind::TURBOFAN);
71 }
72 
CodeKindIsJSFunction(CodeKind kind)73 inline constexpr bool CodeKindIsJSFunction(CodeKind kind) {
74   STATIC_ASSERT(static_cast<int>(CodeKind::BASELINE) + 1 ==
75                 static_cast<int>(CodeKind::MAGLEV));
76   return base::IsInRange(kind, CodeKind::INTERPRETED_FUNCTION,
77                          CodeKind::TURBOFAN);
78 }
79 
CodeKindIsBuiltinOrJSFunction(CodeKind kind)80 inline constexpr bool CodeKindIsBuiltinOrJSFunction(CodeKind kind) {
81   return kind == CodeKind::BUILTIN || CodeKindIsJSFunction(kind);
82 }
83 
CodeKindCanDeoptimize(CodeKind kind)84 inline constexpr bool CodeKindCanDeoptimize(CodeKind kind) {
85   return CodeKindIsOptimizedJSFunction(kind);
86 }
87 
CodeKindCanOSR(CodeKind kind)88 inline constexpr bool CodeKindCanOSR(CodeKind kind) {
89   return kind == CodeKind::TURBOFAN;
90 }
91 
CodeKindCanTierUp(CodeKind kind)92 inline constexpr bool CodeKindCanTierUp(CodeKind kind) {
93   return CodeKindIsUnoptimizedJSFunction(kind);
94 }
95 
96 // TODO(jgruber): Rename or remove this predicate. Currently it means 'is this
97 // kind stored either in the FeedbackVector cache, or in the OSR cache?'.
CodeKindIsStoredInOptimizedCodeCache(CodeKind kind)98 inline constexpr bool CodeKindIsStoredInOptimizedCodeCache(CodeKind kind) {
99   return kind == CodeKind::TURBOFAN;
100 }
101 
CodeKindForTopTier()102 inline CodeKind CodeKindForTopTier() { return CodeKind::TURBOFAN; }
103 
104 // The dedicated CodeKindFlag enum represents all code kinds in a format
105 // suitable for bit sets.
106 enum class CodeKindFlag {
107 #define V(name) name = 1 << static_cast<int>(CodeKind::name),
108   CODE_KIND_LIST(V)
109 #undef V
110 };
111 STATIC_ASSERT(kCodeKindCount <= kInt32Size * kBitsPerByte);
112 
CodeKindToCodeKindFlag(CodeKind kind)113 inline constexpr CodeKindFlag CodeKindToCodeKindFlag(CodeKind kind) {
114 #define V(name) kind == CodeKind::name ? CodeKindFlag::name:
115   return CODE_KIND_LIST(V) CodeKindFlag::INTERPRETED_FUNCTION;
116 #undef V
117 }
118 
119 // CodeKinds represents a set of CodeKind.
120 using CodeKinds = base::Flags<CodeKindFlag>;
DEFINE_OPERATORS_FOR_FLAGS(CodeKinds)121 DEFINE_OPERATORS_FOR_FLAGS(CodeKinds)
122 
123 static constexpr CodeKinds kJSFunctionCodeKindsMask{
124     CodeKindFlag::INTERPRETED_FUNCTION | CodeKindFlag::BASELINE |
125     CodeKindFlag::MAGLEV | CodeKindFlag::TURBOFAN};
126 static constexpr CodeKinds kOptimizedJSFunctionCodeKindsMask{
127     CodeKindFlag::MAGLEV | CodeKindFlag::TURBOFAN};
128 
129 }  // namespace internal
130 }  // namespace v8
131 
132 #endif  // V8_OBJECTS_CODE_KIND_H_
133