v8  10.1.124 (node 18.2.0)
V8 is Google's open source JavaScript engine
name-trait.h
Go to the documentation of this file.
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 INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
6 #define INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
7 
8 #include <cstddef>
9 #include <type_traits>
10 
11 #include "cppgc/name-provider.h"
12 #include "v8config.h" // NOLINT(build/include_directory)
13 
14 namespace cppgc {
15 namespace internal {
16 
17 #if CPPGC_SUPPORTS_OBJECT_NAMES && defined(__clang__)
18 #define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 1
19 
20 // Provides constexpr c-string storage for a name of fixed |Size| characters.
21 // Automatically appends terminating 0 byte.
22 template <size_t Size>
23 struct NameBuffer {
24  char name[Size + 1]{};
25 
26  static constexpr NameBuffer FromCString(const char* str) {
28  for (size_t i = 0; i < Size; ++i) result.name[i] = str[i];
29  result.name[Size] = 0;
30  return result;
31  }
32 };
33 
34 template <typename T>
35 const char* GetTypename() {
36  static constexpr char kSelfPrefix[] =
37  "const char *cppgc::internal::GetTypename() [T =";
38  static_assert(__builtin_strncmp(__PRETTY_FUNCTION__, kSelfPrefix,
39  sizeof(kSelfPrefix) - 1) == 0,
40  "The prefix must match");
41  static constexpr const char* kTypenameStart =
42  __PRETTY_FUNCTION__ + sizeof(kSelfPrefix);
43  static constexpr size_t kTypenameSize =
44  __builtin_strlen(__PRETTY_FUNCTION__) - sizeof(kSelfPrefix) - 1;
45  // NameBuffer is an indirection that is needed to make sure that only a
46  // substring of __PRETTY_FUNCTION__ gets materialized in the binary.
47  static constexpr auto buffer =
49  return buffer.name;
50 }
51 
52 #else
53 #define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 0
54 #endif
55 
57  const char* value;
59 };
60 
62  protected:
64 };
65 
66 // Trait that specifies how the garbage collector retrieves the name for a
67 // given object.
68 template <typename T>
69 class NameTrait final : public NameTraitBase {
70  public:
71  static constexpr bool HasNonHiddenName() {
73  return true;
74 #elif CPPGC_SUPPORTS_OBJECT_NAMES
75  return true;
76 #else // !CPPGC_SUPPORTS_OBJECT_NAMES
77  return std::is_base_of<NameProvider, T>::value;
78 #endif // !CPPGC_SUPPORTS_OBJECT_NAMES
79  }
80 
81  static HeapObjectName GetName(const void* obj) {
82  return GetNameFor(static_cast<const T*>(obj));
83  }
84 
85  private:
86  static HeapObjectName GetNameFor(const NameProvider* name_provider) {
87  return {name_provider->GetHumanReadableName(), false};
88  }
89 
90  static HeapObjectName GetNameFor(...) {
92  return {GetTypename<T>(), false};
93 #elif CPPGC_SUPPORTS_OBJECT_NAMES
94 
95 #if defined(V8_CC_GNU)
96 #define PRETTY_FUNCTION_VALUE __PRETTY_FUNCTION__
97 #elif defined(V8_CC_MSVC)
98 #define PRETTY_FUNCTION_VALUE __FUNCSIG__
99 #else
100 #define PRETTY_FUNCTION_VALUE nullptr
101 #endif
102 
103  static const HeapObjectName leaky_name =
104  GetNameFromTypeSignature(PRETTY_FUNCTION_VALUE);
105  return {leaky_name, false};
106 
107 #undef PRETTY_FUNCTION_VALUE
108 
109 #else // !CPPGC_SUPPORTS_OBJECT_NAMES
110  return {NameProvider::kHiddenName, true};
111 #endif // !CPPGC_SUPPORTS_OBJECT_NAMES
112  }
113 };
114 
115 using NameCallback = HeapObjectName (*)(const void*);
116 
117 } // namespace internal
118 } // namespace cppgc
119 
120 #undef CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
121 
122 #endif // INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_