2020-10-08 11:20:09 +00:00
|
|
|
// Copyright 2020 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#ifndef INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
|
|
|
|
#define INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
|
|
|
|
|
2020-10-08 19:03:04 +00:00
|
|
|
#include <cstddef>
|
|
|
|
|
2020-10-08 11:20:09 +00:00
|
|
|
#include "cppgc/name-provider.h"
|
|
|
|
#include "v8config.h" // NOLINT(build/include_directory)
|
|
|
|
|
|
|
|
namespace cppgc {
|
|
|
|
namespace internal {
|
|
|
|
|
2020-10-08 19:03:04 +00:00
|
|
|
#if CPPGC_SUPPORTS_OBJECT_NAMES && defined(__clang__)
|
|
|
|
#define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 1
|
|
|
|
|
2020-10-09 07:53:31 +00:00
|
|
|
// Provides constexpr c-string storage for a name of fixed |Size| characters.
|
|
|
|
// Automatically appends terminating 0 byte.
|
2020-10-08 19:03:04 +00:00
|
|
|
template <size_t Size>
|
|
|
|
struct NameBuffer {
|
2020-10-09 07:53:31 +00:00
|
|
|
char name[Size + 1]{};
|
2020-10-08 19:03:04 +00:00
|
|
|
|
|
|
|
static constexpr NameBuffer FromCString(const char* str) {
|
|
|
|
NameBuffer result;
|
|
|
|
for (size_t i = 0; i < Size; ++i) result.name[i] = str[i];
|
2020-10-09 07:53:31 +00:00
|
|
|
result.name[Size] = 0;
|
2020-10-08 19:03:04 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
const char* GetTypename() {
|
|
|
|
static constexpr char kSelfPrefix[] =
|
|
|
|
"const char *cppgc::internal::GetTypename() [T =";
|
|
|
|
static_assert(__builtin_strncmp(__PRETTY_FUNCTION__, kSelfPrefix,
|
|
|
|
sizeof(kSelfPrefix) - 1) == 0,
|
|
|
|
"The prefix must match");
|
|
|
|
static constexpr const char* kTypenameStart =
|
|
|
|
__PRETTY_FUNCTION__ + sizeof(kSelfPrefix);
|
|
|
|
static constexpr size_t kTypenameSize =
|
|
|
|
__builtin_strlen(__PRETTY_FUNCTION__) - sizeof(kSelfPrefix) - 1;
|
|
|
|
// NameBuffer is an indirection that is needed to make sure that only a
|
|
|
|
// substring of __PRETTY_FUNCTION__ gets materialized in the binary.
|
|
|
|
static constexpr auto buffer =
|
|
|
|
NameBuffer<kTypenameSize>::FromCString(kTypenameStart);
|
|
|
|
return buffer.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
#define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 0
|
|
|
|
#endif
|
|
|
|
|
2020-10-08 11:20:09 +00:00
|
|
|
struct HeapObjectName {
|
|
|
|
const char* value;
|
|
|
|
bool name_was_hidden;
|
|
|
|
};
|
|
|
|
|
|
|
|
class V8_EXPORT NameTraitBase {
|
|
|
|
protected:
|
|
|
|
static HeapObjectName GetNameFromTypeSignature(const char*);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Trait that specifies how the garbage collector retrieves the name for a
|
|
|
|
// given object.
|
|
|
|
template <typename T>
|
|
|
|
class NameTrait final : public NameTraitBase {
|
|
|
|
public:
|
|
|
|
static HeapObjectName GetName(const void* obj) {
|
|
|
|
return GetNameFor(static_cast<const T*>(obj));
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
static HeapObjectName GetNameFor(const NameProvider* name_provider) {
|
2021-06-08 14:47:01 +00:00
|
|
|
return {name_provider->GetHumanReadableName(), false};
|
2020-10-08 11:20:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HeapObjectName GetNameFor(...) {
|
2020-10-08 19:03:04 +00:00
|
|
|
#if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
|
|
|
|
return {GetTypename<T>(), false};
|
|
|
|
#elif CPPGC_SUPPORTS_OBJECT_NAMES
|
2020-10-08 11:20:09 +00:00
|
|
|
|
|
|
|
#if defined(V8_CC_GNU)
|
|
|
|
#define PRETTY_FUNCTION_VALUE __PRETTY_FUNCTION__
|
|
|
|
#elif defined(V8_CC_MSVC)
|
|
|
|
#define PRETTY_FUNCTION_VALUE __FUNCSIG__
|
|
|
|
#else
|
|
|
|
#define PRETTY_FUNCTION_VALUE nullptr
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static const HeapObjectName leaky_name =
|
|
|
|
GetNameFromTypeSignature(PRETTY_FUNCTION_VALUE);
|
|
|
|
return leaky_name;
|
|
|
|
|
|
|
|
#undef PRETTY_FUNCTION_VALUE
|
|
|
|
|
|
|
|
#else // !CPPGC_SUPPORTS_OBJECT_NAMES
|
|
|
|
return {NameProvider::kHiddenName, true};
|
|
|
|
#endif // !CPPGC_SUPPORTS_OBJECT_NAMES
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
using NameCallback = HeapObjectName (*)(const void*);
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace cppgc
|
|
|
|
|
2020-10-08 19:03:04 +00:00
|
|
|
#undef CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
|
|
|
|
|
2020-10-08 11:20:09 +00:00
|
|
|
#endif // INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
|