Loading...
Searching...
No Matches
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 <cstdint>
10#include <type_traits>
11
12#include "cppgc/name-provider.h"
13#include "v8config.h" // NOLINT(build/include_directory)
14
15namespace cppgc {
16namespace internal {
17
18#if CPPGC_SUPPORTS_OBJECT_NAMES && defined(__clang__)
19#define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 1
20
21// Provides constexpr c-string storage for a name of fixed |Size| characters.
22// Automatically appends terminating 0 byte.
23template <size_t Size>
24struct NameBuffer {
25 char name[Size + 1]{};
26
27 static constexpr NameBuffer FromCString(const char* str) {
28 NameBuffer result;
29 for (size_t i = 0; i < Size; ++i) result.name[i] = str[i];
30 result.name[Size] = 0;
31 return result;
32 }
33};
34
35template <typename T>
36const char* GetTypename() {
37 static constexpr char kSelfPrefix[] =
38 "const char *cppgc::internal::GetTypename() [T =";
39 static_assert(__builtin_strncmp(__PRETTY_FUNCTION__, kSelfPrefix,
40 sizeof(kSelfPrefix) - 1) == 0,
41 "The prefix must match");
42 static constexpr const char* kTypenameStart =
43 __PRETTY_FUNCTION__ + sizeof(kSelfPrefix);
44 static constexpr size_t kTypenameSize =
45 __builtin_strlen(__PRETTY_FUNCTION__) - sizeof(kSelfPrefix) - 1;
46 // NameBuffer is an indirection that is needed to make sure that only a
47 // substring of __PRETTY_FUNCTION__ gets materialized in the binary.
48 static constexpr auto buffer =
49 NameBuffer<kTypenameSize>::FromCString(kTypenameStart);
50 return buffer.name;
51}
52
53#else
54#define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 0
55#endif
56
58 const char* value;
60};
61
62enum class HeapObjectNameForUnnamedObject : uint8_t {
65};
66
68 protected:
70};
71
72// Trait that specifies how the garbage collector retrieves the name for a
73// given object.
74template <typename T>
75class NameTrait final : public NameTraitBase {
76 public:
77 static constexpr bool HasNonHiddenName() {
78#if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
79 return true;
80#elif CPPGC_SUPPORTS_OBJECT_NAMES
81 return true;
82#else // !CPPGC_SUPPORTS_OBJECT_NAMES
83 return std::is_base_of<NameProvider, T>::value;
84#endif // !CPPGC_SUPPORTS_OBJECT_NAMES
85 }
86
88 const void* obj, HeapObjectNameForUnnamedObject name_retrieval_mode) {
89 return GetNameFor(static_cast<const T*>(obj), name_retrieval_mode);
90 }
91
92 private:
93 static HeapObjectName GetNameFor(const NameProvider* name_provider,
95 // Objects inheriting from `NameProvider` are not considered unnamed as
96 // users already provided a name for them.
97 return {name_provider->GetHumanReadableName(), false};
98 }
99
100 static HeapObjectName GetNameFor(
101 const void*, HeapObjectNameForUnnamedObject name_retrieval_mode) {
102 if (name_retrieval_mode == HeapObjectNameForUnnamedObject::kUseHiddenName)
103 return {NameProvider::kHiddenName, true};
104
105#if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
106 return {GetTypename<T>(), false};
107#elif CPPGC_SUPPORTS_OBJECT_NAMES
108
109#if defined(V8_CC_GNU)
110#define PRETTY_FUNCTION_VALUE __PRETTY_FUNCTION__
111#elif defined(V8_CC_MSVC)
112#define PRETTY_FUNCTION_VALUE __FUNCSIG__
113#else
114#define PRETTY_FUNCTION_VALUE nullptr
115#endif
116
117 static const HeapObjectName leaky_name =
118 GetNameFromTypeSignature(PRETTY_FUNCTION_VALUE);
119 return leaky_name;
120
121#undef PRETTY_FUNCTION_VALUE
122
123#else // !CPPGC_SUPPORTS_OBJECT_NAMES
124 // We wanted to use a class name but were unable to provide one due to
125 // compiler limitations or build configuration. As such, return the hidden
126 // name with name_was_hidden=false, which will cause this object to be
127 // visible in the snapshot.
128 return {NameProvider::kHiddenName, false};
129#endif // !CPPGC_SUPPORTS_OBJECT_NAMES
130 }
131};
132
133using NameCallback = HeapObjectName (*)(const void*,
135
136} // namespace internal
137} // namespace cppgc
138
139#undef CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
140
141#endif // INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
Definition: name-provider.h:26
static constexpr const char kHiddenName[]
Definition: name-provider.h:31
virtual const char * GetHumanReadableName() const =0
Definition: name-trait.h:67
static HeapObjectName GetNameFromTypeSignature(const char *)
Definition: name-trait.h:75
static constexpr bool HasNonHiddenName()
Definition: name-trait.h:77
static HeapObjectName GetName(const void *obj, HeapObjectNameForUnnamedObject name_retrieval_mode)
Definition: name-trait.h:87
HeapObjectName(*)(const void *, HeapObjectNameForUnnamedObject) NameCallback
Definition: name-trait.h:134
HeapObjectNameForUnnamedObject
Definition: name-trait.h:62
Definition: allocation.h:38
Definition: name-trait.h:57
const char * value
Definition: name-trait.h:58
bool name_was_hidden
Definition: name-trait.h:59
#define V8_EXPORT
Definition: v8config.h:793