11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_OBJECTS_CODE_KIND_H_
61cb0ef41Sopenharmony_ci#define V8_OBJECTS_CODE_KIND_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/bounds.h"
91cb0ef41Sopenharmony_ci#include "src/base/flags.h"
101cb0ef41Sopenharmony_ci#include "src/flags/flags.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace v8 {
131cb0ef41Sopenharmony_cinamespace internal {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// The order of INTERPRETED_FUNCTION to TURBOFAN is important. We use it to
161cb0ef41Sopenharmony_ci// check the relative ordering of the tiers when fetching / installing optimized
171cb0ef41Sopenharmony_ci// code.
181cb0ef41Sopenharmony_ci#define CODE_KIND_LIST(V)  \
191cb0ef41Sopenharmony_ci  V(BYTECODE_HANDLER)      \
201cb0ef41Sopenharmony_ci  V(FOR_TESTING)           \
211cb0ef41Sopenharmony_ci  V(BUILTIN)               \
221cb0ef41Sopenharmony_ci  V(REGEXP)                \
231cb0ef41Sopenharmony_ci  V(WASM_FUNCTION)         \
241cb0ef41Sopenharmony_ci  V(WASM_TO_CAPI_FUNCTION) \
251cb0ef41Sopenharmony_ci  V(WASM_TO_JS_FUNCTION)   \
261cb0ef41Sopenharmony_ci  V(JS_TO_WASM_FUNCTION)   \
271cb0ef41Sopenharmony_ci  V(JS_TO_JS_FUNCTION)     \
281cb0ef41Sopenharmony_ci  V(C_WASM_ENTRY)          \
291cb0ef41Sopenharmony_ci  V(INTERPRETED_FUNCTION)  \
301cb0ef41Sopenharmony_ci  V(BASELINE)              \
311cb0ef41Sopenharmony_ci  V(MAGLEV)                \
321cb0ef41Sopenharmony_ci  V(TURBOFAN)
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_cienum class CodeKind : uint8_t {
351cb0ef41Sopenharmony_ci#define DEFINE_CODE_KIND_ENUM(name) name,
361cb0ef41Sopenharmony_ci  CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
371cb0ef41Sopenharmony_ci#undef DEFINE_CODE_KIND_ENUM
381cb0ef41Sopenharmony_ci};
391cb0ef41Sopenharmony_ciSTATIC_ASSERT(CodeKind::INTERPRETED_FUNCTION < CodeKind::BASELINE);
401cb0ef41Sopenharmony_ciSTATIC_ASSERT(CodeKind::BASELINE < CodeKind::TURBOFAN);
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci#define V(...) +1
431cb0ef41Sopenharmony_cistatic constexpr int kCodeKindCount = CODE_KIND_LIST(V);
441cb0ef41Sopenharmony_ci#undef V
451cb0ef41Sopenharmony_ci// Unlikely, but just to be safe:
461cb0ef41Sopenharmony_ciSTATIC_ASSERT(kCodeKindCount <= std::numeric_limits<uint8_t>::max());
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ciconst char* CodeKindToString(CodeKind kind);
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ciconst char* CodeKindToMarker(CodeKind kind);
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ciinline constexpr bool CodeKindIsInterpretedJSFunction(CodeKind kind) {
531cb0ef41Sopenharmony_ci  return kind == CodeKind::INTERPRETED_FUNCTION;
541cb0ef41Sopenharmony_ci}
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ciinline constexpr bool CodeKindIsBaselinedJSFunction(CodeKind kind) {
571cb0ef41Sopenharmony_ci  return kind == CodeKind::BASELINE;
581cb0ef41Sopenharmony_ci}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ciinline constexpr bool CodeKindIsUnoptimizedJSFunction(CodeKind kind) {
611cb0ef41Sopenharmony_ci  STATIC_ASSERT(static_cast<int>(CodeKind::INTERPRETED_FUNCTION) + 1 ==
621cb0ef41Sopenharmony_ci                static_cast<int>(CodeKind::BASELINE));
631cb0ef41Sopenharmony_ci  return base::IsInRange(kind, CodeKind::INTERPRETED_FUNCTION,
641cb0ef41Sopenharmony_ci                         CodeKind::BASELINE);
651cb0ef41Sopenharmony_ci}
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ciinline constexpr bool CodeKindIsOptimizedJSFunction(CodeKind kind) {
681cb0ef41Sopenharmony_ci  STATIC_ASSERT(static_cast<int>(CodeKind::MAGLEV) + 1 ==
691cb0ef41Sopenharmony_ci                static_cast<int>(CodeKind::TURBOFAN));
701cb0ef41Sopenharmony_ci  return base::IsInRange(kind, CodeKind::MAGLEV, CodeKind::TURBOFAN);
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ciinline constexpr bool CodeKindIsJSFunction(CodeKind kind) {
741cb0ef41Sopenharmony_ci  STATIC_ASSERT(static_cast<int>(CodeKind::BASELINE) + 1 ==
751cb0ef41Sopenharmony_ci                static_cast<int>(CodeKind::MAGLEV));
761cb0ef41Sopenharmony_ci  return base::IsInRange(kind, CodeKind::INTERPRETED_FUNCTION,
771cb0ef41Sopenharmony_ci                         CodeKind::TURBOFAN);
781cb0ef41Sopenharmony_ci}
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ciinline constexpr bool CodeKindIsBuiltinOrJSFunction(CodeKind kind) {
811cb0ef41Sopenharmony_ci  return kind == CodeKind::BUILTIN || CodeKindIsJSFunction(kind);
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciinline constexpr bool CodeKindCanDeoptimize(CodeKind kind) {
851cb0ef41Sopenharmony_ci  return CodeKindIsOptimizedJSFunction(kind);
861cb0ef41Sopenharmony_ci}
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ciinline constexpr bool CodeKindCanOSR(CodeKind kind) {
891cb0ef41Sopenharmony_ci  return kind == CodeKind::TURBOFAN;
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ciinline constexpr bool CodeKindCanTierUp(CodeKind kind) {
931cb0ef41Sopenharmony_ci  return CodeKindIsUnoptimizedJSFunction(kind);
941cb0ef41Sopenharmony_ci}
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci// TODO(jgruber): Rename or remove this predicate. Currently it means 'is this
971cb0ef41Sopenharmony_ci// kind stored either in the FeedbackVector cache, or in the OSR cache?'.
981cb0ef41Sopenharmony_ciinline constexpr bool CodeKindIsStoredInOptimizedCodeCache(CodeKind kind) {
991cb0ef41Sopenharmony_ci  return kind == CodeKind::TURBOFAN;
1001cb0ef41Sopenharmony_ci}
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ciinline CodeKind CodeKindForTopTier() { return CodeKind::TURBOFAN; }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci// The dedicated CodeKindFlag enum represents all code kinds in a format
1051cb0ef41Sopenharmony_ci// suitable for bit sets.
1061cb0ef41Sopenharmony_cienum class CodeKindFlag {
1071cb0ef41Sopenharmony_ci#define V(name) name = 1 << static_cast<int>(CodeKind::name),
1081cb0ef41Sopenharmony_ci  CODE_KIND_LIST(V)
1091cb0ef41Sopenharmony_ci#undef V
1101cb0ef41Sopenharmony_ci};
1111cb0ef41Sopenharmony_ciSTATIC_ASSERT(kCodeKindCount <= kInt32Size * kBitsPerByte);
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciinline constexpr CodeKindFlag CodeKindToCodeKindFlag(CodeKind kind) {
1141cb0ef41Sopenharmony_ci#define V(name) kind == CodeKind::name ? CodeKindFlag::name:
1151cb0ef41Sopenharmony_ci  return CODE_KIND_LIST(V) CodeKindFlag::INTERPRETED_FUNCTION;
1161cb0ef41Sopenharmony_ci#undef V
1171cb0ef41Sopenharmony_ci}
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci// CodeKinds represents a set of CodeKind.
1201cb0ef41Sopenharmony_ciusing CodeKinds = base::Flags<CodeKindFlag>;
1211cb0ef41Sopenharmony_ciDEFINE_OPERATORS_FOR_FLAGS(CodeKinds)
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_cistatic constexpr CodeKinds kJSFunctionCodeKindsMask{
1241cb0ef41Sopenharmony_ci    CodeKindFlag::INTERPRETED_FUNCTION | CodeKindFlag::BASELINE |
1251cb0ef41Sopenharmony_ci    CodeKindFlag::MAGLEV | CodeKindFlag::TURBOFAN};
1261cb0ef41Sopenharmony_cistatic constexpr CodeKinds kOptimizedJSFunctionCodeKindsMask{
1271cb0ef41Sopenharmony_ci    CodeKindFlag::MAGLEV | CodeKindFlag::TURBOFAN};
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci}  // namespace internal
1301cb0ef41Sopenharmony_ci}  // namespace v8
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci#endif  // V8_OBJECTS_CODE_KIND_H_
133