Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 10:08:50

0001 // Copyright 2020 the V8 project authors. All rights reserved.
0002 // Use of this source code is governed by a BSD-style license that can be
0003 // found in the LICENSE file.
0004 
0005 #ifndef INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
0006 #define INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
0007 
0008 #include <cstddef>
0009 #include <cstdint>
0010 #include <type_traits>
0011 
0012 #include "cppgc/name-provider.h"
0013 #include "v8config.h"  // NOLINT(build/include_directory)
0014 
0015 namespace cppgc {
0016 namespace internal {
0017 
0018 #if CPPGC_SUPPORTS_OBJECT_NAMES && defined(__clang__)
0019 #define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 1
0020 
0021 // Provides constexpr c-string storage for a name of fixed |Size| characters.
0022 // Automatically appends terminating 0 byte.
0023 template <size_t Size>
0024 struct NameBuffer {
0025   char name[Size + 1]{};
0026 
0027   static constexpr NameBuffer FromCString(const char* str) {
0028     NameBuffer result;
0029     for (size_t i = 0; i < Size; ++i) result.name[i] = str[i];
0030     result.name[Size] = 0;
0031     return result;
0032   }
0033 };
0034 
0035 template <typename T>
0036 const char* GetTypename() {
0037   static constexpr char kSelfPrefix[] =
0038       "const char *cppgc::internal::GetTypename() [T =";
0039   static_assert(__builtin_strncmp(__PRETTY_FUNCTION__, kSelfPrefix,
0040                                   sizeof(kSelfPrefix) - 1) == 0,
0041                 "The prefix must match");
0042   static constexpr const char* kTypenameStart =
0043       __PRETTY_FUNCTION__ + sizeof(kSelfPrefix);
0044   static constexpr size_t kTypenameSize =
0045       __builtin_strlen(__PRETTY_FUNCTION__) - sizeof(kSelfPrefix) - 1;
0046   // NameBuffer is an indirection that is needed to make sure that only a
0047   // substring of __PRETTY_FUNCTION__ gets materialized in the binary.
0048   static constexpr auto buffer =
0049       NameBuffer<kTypenameSize>::FromCString(kTypenameStart);
0050   return buffer.name;
0051 }
0052 
0053 #else
0054 #define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 0
0055 #endif
0056 
0057 struct HeapObjectName {
0058   const char* value;
0059   bool name_was_hidden;
0060 };
0061 
0062 enum class HeapObjectNameForUnnamedObject : uint8_t {
0063   kUseClassNameIfSupported,
0064   kUseHiddenName,
0065 };
0066 
0067 class V8_EXPORT NameTraitBase {
0068  protected:
0069   static HeapObjectName GetNameFromTypeSignature(const char*);
0070 };
0071 
0072 // Trait that specifies how the garbage collector retrieves the name for a
0073 // given object.
0074 template <typename T>
0075 class NameTrait final : public NameTraitBase {
0076  public:
0077   static constexpr bool HasNonHiddenName() {
0078 #if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
0079     return true;
0080 #elif CPPGC_SUPPORTS_OBJECT_NAMES
0081     return true;
0082 #else   // !CPPGC_SUPPORTS_OBJECT_NAMES
0083     return std::is_base_of<NameProvider, T>::value;
0084 #endif  // !CPPGC_SUPPORTS_OBJECT_NAMES
0085   }
0086 
0087   static HeapObjectName GetName(
0088       const void* obj, HeapObjectNameForUnnamedObject name_retrieval_mode) {
0089     return GetNameFor(static_cast<const T*>(obj), name_retrieval_mode);
0090   }
0091 
0092  private:
0093   static HeapObjectName GetNameFor(const NameProvider* name_provider,
0094                                    HeapObjectNameForUnnamedObject) {
0095     // Objects inheriting from `NameProvider` are not considered unnamed as
0096     // users already provided a name for them.
0097     return {name_provider->GetHumanReadableName(), false};
0098   }
0099 
0100   static HeapObjectName GetNameFor(
0101       const void*, HeapObjectNameForUnnamedObject name_retrieval_mode) {
0102     if (name_retrieval_mode == HeapObjectNameForUnnamedObject::kUseHiddenName)
0103       return {NameProvider::kHiddenName, true};
0104 
0105 #if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
0106     return {GetTypename<T>(), false};
0107 #elif CPPGC_SUPPORTS_OBJECT_NAMES
0108 
0109 #if defined(V8_CC_GNU)
0110 #define PRETTY_FUNCTION_VALUE __PRETTY_FUNCTION__
0111 #elif defined(V8_CC_MSVC)
0112 #define PRETTY_FUNCTION_VALUE __FUNCSIG__
0113 #else
0114 #define PRETTY_FUNCTION_VALUE nullptr
0115 #endif
0116 
0117     static const HeapObjectName leaky_name =
0118         GetNameFromTypeSignature(PRETTY_FUNCTION_VALUE);
0119     return leaky_name;
0120 
0121 #undef PRETTY_FUNCTION_VALUE
0122 
0123 #else   // !CPPGC_SUPPORTS_OBJECT_NAMES
0124     return {NameProvider::kHiddenName, true};
0125 #endif  // !CPPGC_SUPPORTS_OBJECT_NAMES
0126   }
0127 };
0128 
0129 using NameCallback = HeapObjectName (*)(const void*,
0130                                         HeapObjectNameForUnnamedObject);
0131 
0132 }  // namespace internal
0133 }  // namespace cppgc
0134 
0135 #undef CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
0136 
0137 #endif  // INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_