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