Commit 93f8a867 authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

Reland "[cpu-profiler] Use base::LeakyObject for static CodeEntry objects"

This is a reland of c594a20e

Moved the getters to the .cc file to avoid link problems as they
are not performance critical anyway.

Moved ProfileNode::source_type to cc as it uses the _entry() functions
which are no longer inline.

Original change's description:
> [cpu-profiler] Use base::LeakyObject for static CodeEntry objects
>
> This is preferred over the older LazyInstance based stuff, and has
> a lot less boilerplate and is easier to follow.
>
> Bug: v8:8600
> Change-Id: I7c5c5ae04c064b0fc598dc01f1ed5442dc21a17b
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2640475
> Commit-Queue: Peter Marshall <petermarshall@chromium.org>
> Reviewed-by: Clemens Backes <clemensb@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#72224}

Bug: v8:8600
Cq-Include-Trybots: luci.v8.try:v8_linux64_ubsan_rel_ng
Change-Id: I0ad9118e6d3bd087707609714b20aee1cbc4f459
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2642252
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72254}
parent 51ecfaec
......@@ -10823,6 +10823,9 @@ const CpuProfileNode* CpuProfile::GetSample(int index) const {
return reinterpret_cast<const CpuProfileNode*>(profile->sample(index).node);
}
const int CpuProfileNode::kNoLineNumberInfo;
const int CpuProfileNode::kNoColumnNumberInfo;
int64_t CpuProfile::GetSampleTimestamp(int index) const {
const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
return profile->sample(index).timestamp.since_origin().InMicroseconds();
......
......@@ -40,48 +40,6 @@ ProfileNode::ProfileNode(ProfileTree* tree, CodeEntry* entry,
tree_->EnqueueNode(this);
}
inline CpuProfileNode::SourceType ProfileNode::source_type() const {
// Handle metadata and VM state code entry types.
if (entry_ == CodeEntry::program_entry() ||
entry_ == CodeEntry::idle_entry() || entry_ == CodeEntry::gc_entry() ||
entry_ == CodeEntry::root_entry()) {
return CpuProfileNode::kInternal;
}
if (entry_ == CodeEntry::unresolved_entry())
return CpuProfileNode::kUnresolved;
// Otherwise, resolve based on logger tag.
switch (entry_->tag()) {
case CodeEventListener::EVAL_TAG:
case CodeEventListener::SCRIPT_TAG:
case CodeEventListener::LAZY_COMPILE_TAG:
case CodeEventListener::FUNCTION_TAG:
case CodeEventListener::INTERPRETED_FUNCTION_TAG:
return CpuProfileNode::kScript;
case CodeEventListener::BUILTIN_TAG:
case CodeEventListener::HANDLER_TAG:
case CodeEventListener::BYTECODE_HANDLER_TAG:
case CodeEventListener::NATIVE_FUNCTION_TAG:
case CodeEventListener::NATIVE_SCRIPT_TAG:
case CodeEventListener::NATIVE_LAZY_COMPILE_TAG:
return CpuProfileNode::kBuiltin;
case CodeEventListener::CALLBACK_TAG:
return CpuProfileNode::kCallback;
case CodeEventListener::REG_EXP_TAG:
case CodeEventListener::STUB_TAG:
case CodeEventListener::CODE_CREATION_EVENT:
case CodeEventListener::CODE_DISABLE_OPT_EVENT:
case CodeEventListener::CODE_MOVE_EVENT:
case CodeEventListener::CODE_DELETE_EVENT:
case CodeEventListener::CODE_MOVING_GC:
case CodeEventListener::SHARED_FUNC_MOVE_EVENT:
case CodeEventListener::SNAPSHOT_CODE_NAME_EVENT:
case CodeEventListener::TICK_EVENT:
case CodeEventListener::NUMBER_OF_LOG_EVENTS:
return CpuProfileNode::kInternal;
}
}
inline Isolate* ProfileNode::isolate() const { return tree_->isolate(); }
} // namespace internal
......
......@@ -6,6 +6,8 @@
#include <algorithm>
#include "include/v8-profiler.h"
#include "src/base/lazy-instance.h"
#include "src/codegen/source-position.h"
#include "src/objects/shared-function-info-inl.h"
#include "src/profiler/cpu-profiler.h"
......@@ -81,60 +83,54 @@ const char* const CodeEntry::kGarbageCollectorEntryName = "(garbage collector)";
const char* const CodeEntry::kUnresolvedFunctionName = "(unresolved function)";
const char* const CodeEntry::kRootEntryName = "(root)";
base::LazyDynamicInstance<CodeEntry, CodeEntry::ProgramEntryCreateTrait>::type
CodeEntry::kProgramEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
base::LazyDynamicInstance<CodeEntry, CodeEntry::IdleEntryCreateTrait>::type
CodeEntry::kIdleEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
base::LazyDynamicInstance<CodeEntry, CodeEntry::GCEntryCreateTrait>::type
CodeEntry::kGCEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
base::LazyDynamicInstance<CodeEntry,
CodeEntry::UnresolvedEntryCreateTrait>::type
CodeEntry::kUnresolvedEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
base::LazyDynamicInstance<CodeEntry, CodeEntry::RootEntryCreateTrait>::type
CodeEntry::kRootEntry = LAZY_DYNAMIC_INSTANCE_INITIALIZER;
CodeEntry* CodeEntry::ProgramEntryCreateTrait::Create() {
return new CodeEntry(
// static
CodeEntry* CodeEntry::program_entry() {
static base::LeakyObject<CodeEntry> kProgramEntry(
CodeEventListener::FUNCTION_TAG, CodeEntry::kProgramEntryName,
CodeEntry::kEmptyResourceName, v8::CpuProfileNode::kNoLineNumberInfo,
v8::CpuProfileNode::kNoColumnNumberInfo, nullptr, false,
CodeEntry::CodeType::OTHER);
return kProgramEntry.get();
}
CodeEntry* CodeEntry::IdleEntryCreateTrait::Create() {
return new CodeEntry(CodeEventListener::FUNCTION_TAG,
CodeEntry::kIdleEntryName, CodeEntry::kEmptyResourceName,
v8::CpuProfileNode::kNoLineNumberInfo,
v8::CpuProfileNode::kNoColumnNumberInfo, nullptr, false,
CodeEntry::CodeType::OTHER);
// static
CodeEntry* CodeEntry::idle_entry() {
static base::LeakyObject<CodeEntry> kIdleEntry(
CodeEventListener::FUNCTION_TAG, CodeEntry::kIdleEntryName,
CodeEntry::kEmptyResourceName, v8::CpuProfileNode::kNoLineNumberInfo,
v8::CpuProfileNode::kNoColumnNumberInfo, nullptr, false,
CodeEntry::CodeType::OTHER);
return kIdleEntry.get();
}
CodeEntry* CodeEntry::GCEntryCreateTrait::Create() {
return new CodeEntry(
// static
CodeEntry* CodeEntry::gc_entry() {
static base::LeakyObject<CodeEntry> kGcEntry(
CodeEventListener::BUILTIN_TAG, CodeEntry::kGarbageCollectorEntryName,
CodeEntry::kEmptyResourceName, v8::CpuProfileNode::kNoLineNumberInfo,
v8::CpuProfileNode::kNoColumnNumberInfo, nullptr, false,
CodeEntry::CodeType::OTHER);
return kGcEntry.get();
}
CodeEntry* CodeEntry::UnresolvedEntryCreateTrait::Create() {
return new CodeEntry(
// static
CodeEntry* CodeEntry::unresolved_entry() {
static base::LeakyObject<CodeEntry> kUnresolvedEntry(
CodeEventListener::FUNCTION_TAG, CodeEntry::kUnresolvedFunctionName,
CodeEntry::kEmptyResourceName, v8::CpuProfileNode::kNoLineNumberInfo,
v8::CpuProfileNode::kNoColumnNumberInfo, nullptr, false,
CodeEntry::CodeType::OTHER);
return kUnresolvedEntry.get();
}
CodeEntry* CodeEntry::RootEntryCreateTrait::Create() {
return new CodeEntry(CodeEventListener::FUNCTION_TAG,
CodeEntry::kRootEntryName, CodeEntry::kEmptyResourceName,
v8::CpuProfileNode::kNoLineNumberInfo,
v8::CpuProfileNode::kNoColumnNumberInfo, nullptr, false,
CodeEntry::CodeType::OTHER);
// static
CodeEntry* CodeEntry::root_entry() {
static base::LeakyObject<CodeEntry> kRootEntry(
CodeEventListener::FUNCTION_TAG, CodeEntry::kRootEntryName,
CodeEntry::kEmptyResourceName, v8::CpuProfileNode::kNoLineNumberInfo,
v8::CpuProfileNode::kNoColumnNumberInfo, nullptr, false,
CodeEntry::CodeType::OTHER);
return kRootEntry.get();
}
uint32_t CodeEntry::GetHash() const {
......@@ -302,6 +298,48 @@ void CodeEntry::print() const {
base::OS::Print("\n");
}
CpuProfileNode::SourceType ProfileNode::source_type() const {
// Handle metadata and VM state code entry types.
if (entry_ == CodeEntry::program_entry() ||
entry_ == CodeEntry::idle_entry() || entry_ == CodeEntry::gc_entry() ||
entry_ == CodeEntry::root_entry()) {
return CpuProfileNode::kInternal;
}
if (entry_ == CodeEntry::unresolved_entry())
return CpuProfileNode::kUnresolved;
// Otherwise, resolve based on logger tag.
switch (entry_->tag()) {
case CodeEventListener::EVAL_TAG:
case CodeEventListener::SCRIPT_TAG:
case CodeEventListener::LAZY_COMPILE_TAG:
case CodeEventListener::FUNCTION_TAG:
case CodeEventListener::INTERPRETED_FUNCTION_TAG:
return CpuProfileNode::kScript;
case CodeEventListener::BUILTIN_TAG:
case CodeEventListener::HANDLER_TAG:
case CodeEventListener::BYTECODE_HANDLER_TAG:
case CodeEventListener::NATIVE_FUNCTION_TAG:
case CodeEventListener::NATIVE_SCRIPT_TAG:
case CodeEventListener::NATIVE_LAZY_COMPILE_TAG:
return CpuProfileNode::kBuiltin;
case CodeEventListener::CALLBACK_TAG:
return CpuProfileNode::kCallback;
case CodeEventListener::REG_EXP_TAG:
case CodeEventListener::STUB_TAG:
case CodeEventListener::CODE_CREATION_EVENT:
case CodeEventListener::CODE_DISABLE_OPT_EVENT:
case CodeEventListener::CODE_MOVE_EVENT:
case CodeEventListener::CODE_DELETE_EVENT:
case CodeEventListener::CODE_MOVING_GC:
case CodeEventListener::SHARED_FUNC_MOVE_EVENT:
case CodeEventListener::SNAPSHOT_CODE_NAME_EVENT:
case CodeEventListener::TICK_EVENT:
case CodeEventListener::NUMBER_OF_LOG_EVENTS:
return CpuProfileNode::kInternal;
}
}
void ProfileNode::CollectDeoptInfo(CodeEntry* entry) {
deopt_infos_.push_back(entry->GetDeoptInfo());
entry->clear_deopt_info();
......
......@@ -162,21 +162,17 @@ class CodeEntry {
V8_EXPORT_PRIVATE static const char* const kProgramEntryName;
V8_EXPORT_PRIVATE static const char* const kIdleEntryName;
static const char* const kGarbageCollectorEntryName;
V8_EXPORT_PRIVATE static const char* const kGarbageCollectorEntryName;
// Used to represent frames for which we have no reliable way to
// detect function.
V8_EXPORT_PRIVATE static const char* const kUnresolvedFunctionName;
V8_EXPORT_PRIVATE static const char* const kRootEntryName;
V8_INLINE static CodeEntry* program_entry() {
return kProgramEntry.Pointer();
}
V8_INLINE static CodeEntry* idle_entry() { return kIdleEntry.Pointer(); }
V8_INLINE static CodeEntry* gc_entry() { return kGCEntry.Pointer(); }
V8_INLINE static CodeEntry* unresolved_entry() {
return kUnresolvedEntry.Pointer();
}
V8_INLINE static CodeEntry* root_entry() { return kRootEntry.Pointer(); }
V8_EXPORT_PRIVATE static CodeEntry* program_entry();
V8_EXPORT_PRIVATE static CodeEntry* idle_entry();
V8_EXPORT_PRIVATE static CodeEntry* gc_entry();
V8_EXPORT_PRIVATE static CodeEntry* unresolved_entry();
V8_EXPORT_PRIVATE static CodeEntry* root_entry();
// Releases strings owned by this CodeEntry, which may be allocated in the
// provided StringsStorage instance. This instance is not stored directly
......@@ -199,33 +195,6 @@ class CodeEntry {
RareData* EnsureRareData();
struct V8_EXPORT_PRIVATE ProgramEntryCreateTrait {
static CodeEntry* Create();
};
struct V8_EXPORT_PRIVATE IdleEntryCreateTrait {
static CodeEntry* Create();
};
struct V8_EXPORT_PRIVATE GCEntryCreateTrait {
static CodeEntry* Create();
};
struct V8_EXPORT_PRIVATE UnresolvedEntryCreateTrait {
static CodeEntry* Create();
};
struct V8_EXPORT_PRIVATE RootEntryCreateTrait {
static CodeEntry* Create();
};
V8_EXPORT_PRIVATE static base::LazyDynamicInstance<
CodeEntry, ProgramEntryCreateTrait>::type kProgramEntry;
V8_EXPORT_PRIVATE static base::LazyDynamicInstance<
CodeEntry, IdleEntryCreateTrait>::type kIdleEntry;
V8_EXPORT_PRIVATE static base::LazyDynamicInstance<
CodeEntry, GCEntryCreateTrait>::type kGCEntry;
V8_EXPORT_PRIVATE static base::LazyDynamicInstance<
CodeEntry, UnresolvedEntryCreateTrait>::type kUnresolvedEntry;
V8_EXPORT_PRIVATE static base::LazyDynamicInstance<
CodeEntry, RootEntryCreateTrait>::type kRootEntry;
using TagField = base::BitField<CodeEventListener::LogEventsAndTags, 0, 8>;
using BuiltinIdField = base::BitField<Builtins::Name, 8, 20>;
static_assert(Builtins::builtin_count <= BuiltinIdField::kNumValues,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment