[cpu-profiler] Remove name_prefix field from CodeEntry
We can save a pointer of space for each CodeEntry by removing this field which we don't really need. Instead of concatenating the name string on demand, concatenate the prefix eagerly. Reduces sizeof(CodeEntry) from 136 to 128 on 64-bit. Bug: v8:7719 Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Change-Id: Id346a8f36794e337e8c886f8d1969431424539b0 Reviewed-on: https://chromium-review.googlesource.com/1039825 Reviewed-by: Yang Guo <yangguo@chromium.org> Reviewed-by: Alexei Filippov <alph@chromium.org> Commit-Queue: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#53014}
This commit is contained in:
parent
633910e6e5
commit
6f72af25fe
10
src/api.cc
10
src/api.cc
@ -9836,15 +9836,7 @@ Local<String> CpuProfileNode::GetFunctionName() const {
|
||||
const i::CodeEntry* entry = node->entry();
|
||||
i::Handle<i::String> name =
|
||||
isolate->factory()->InternalizeUtf8String(entry->name());
|
||||
if (!entry->has_name_prefix()) {
|
||||
return ToApiHandle<String>(name);
|
||||
} else {
|
||||
// We do not expect this to fail. Change this if it does.
|
||||
i::Handle<i::String> cons = isolate->factory()->NewConsString(
|
||||
isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
|
||||
name).ToHandleChecked();
|
||||
return ToApiHandle<String>(cons);
|
||||
}
|
||||
return ToApiHandle<String>(name);
|
||||
}
|
||||
|
||||
int debug::Coverage::BlockData::StartOffset() const { return block_->start; }
|
||||
|
@ -328,9 +328,8 @@ void CpuProfiler::CreateEntriesForRuntimeCallStats() {
|
||||
for (int i = 0; i < RuntimeCallStats::kNumberOfCounters; ++i) {
|
||||
RuntimeCallCounter* counter = rcs->GetCounter(i);
|
||||
DCHECK(counter->name());
|
||||
std::unique_ptr<CodeEntry> entry(
|
||||
new CodeEntry(CodeEventListener::FUNCTION_TAG, counter->name(),
|
||||
CodeEntry::kEmptyNamePrefix, "native V8Runtime"));
|
||||
std::unique_ptr<CodeEntry> entry(new CodeEntry(
|
||||
CodeEventListener::FUNCTION_TAG, counter->name(), "native V8Runtime"));
|
||||
code_map->AddCode(reinterpret_cast<Address>(counter), entry.get(), 1);
|
||||
static_entries_.push_back(std::move(entry));
|
||||
}
|
||||
|
@ -11,13 +11,12 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
CodeEntry::CodeEntry(CodeEventListener::LogEventsAndTags tag, const char* name,
|
||||
const char* name_prefix, const char* resource_name,
|
||||
int line_number, int column_number,
|
||||
const char* resource_name, int line_number,
|
||||
int column_number,
|
||||
std::unique_ptr<SourcePositionTable> line_info,
|
||||
Address instruction_start)
|
||||
: bit_field_(TagField::encode(tag) |
|
||||
BuiltinIdField::encode(Builtins::builtin_count)),
|
||||
name_prefix_(name_prefix),
|
||||
name_(name),
|
||||
resource_name_(resource_name),
|
||||
line_number_(line_number),
|
||||
|
@ -39,8 +39,6 @@ int SourcePositionTable::GetSourceLineNumber(int pc_offset) const {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
const char* const CodeEntry::kEmptyNamePrefix = "";
|
||||
const char* const CodeEntry::kEmptyResourceName = "";
|
||||
const char* const CodeEntry::kEmptyBailoutReason = "";
|
||||
const char* const CodeEntry::kNoDeoptReason = "";
|
||||
@ -87,8 +85,6 @@ uint32_t CodeEntry::GetHash() const {
|
||||
hash ^= ComputeIntegerHash(static_cast<uint32_t>(script_id_));
|
||||
hash ^= ComputeIntegerHash(static_cast<uint32_t>(position_));
|
||||
} else {
|
||||
hash ^= ComputeIntegerHash(
|
||||
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_prefix_)));
|
||||
hash ^= ComputeIntegerHash(
|
||||
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name_)));
|
||||
hash ^= ComputeIntegerHash(
|
||||
@ -103,8 +99,7 @@ bool CodeEntry::IsSameFunctionAs(const CodeEntry* entry) const {
|
||||
if (script_id_ != v8::UnboundScript::kNoScriptId) {
|
||||
return script_id_ == entry->script_id_ && position_ == entry->position_;
|
||||
}
|
||||
return name_prefix_ == entry->name_prefix_ && name_ == entry->name_ &&
|
||||
resource_name_ == entry->resource_name_ &&
|
||||
return name_ == entry->name_ && resource_name_ == entry->resource_name_ &&
|
||||
line_number_ == entry->line_number_;
|
||||
}
|
||||
|
||||
@ -224,9 +219,8 @@ bool ProfileNode::GetLineTicks(v8::CpuProfileNode::LineTick* entries,
|
||||
|
||||
|
||||
void ProfileNode::Print(int indent) {
|
||||
base::OS::Print("%5u %*s %s%s %d #%d", self_ticks_, indent, "",
|
||||
entry_->name_prefix(), entry_->name(), entry_->script_id(),
|
||||
id());
|
||||
base::OS::Print("%5u %*s %s %d #%d", self_ticks_, indent, "", entry_->name(),
|
||||
entry_->script_id(), id());
|
||||
if (entry_->resource_name()[0] != '\0')
|
||||
base::OS::Print(" %s:%d", entry_->resource_name(), entry_->line_number());
|
||||
base::OS::Print("\n");
|
||||
|
@ -42,15 +42,12 @@ class CodeEntry {
|
||||
public:
|
||||
// CodeEntry doesn't own name strings, just references them.
|
||||
inline CodeEntry(CodeEventListener::LogEventsAndTags tag, const char* name,
|
||||
const char* name_prefix = CodeEntry::kEmptyNamePrefix,
|
||||
const char* resource_name = CodeEntry::kEmptyResourceName,
|
||||
int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
|
||||
int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
|
||||
std::unique_ptr<SourcePositionTable> line_info = nullptr,
|
||||
Address instruction_start = kNullAddress);
|
||||
|
||||
const char* name_prefix() const { return name_prefix_; }
|
||||
bool has_name_prefix() const { return name_prefix_[0] != '\0'; }
|
||||
const char* name() const { return name_; }
|
||||
const char* resource_name() const { return resource_name_; }
|
||||
int line_number() const { return line_number_; }
|
||||
@ -102,7 +99,6 @@ class CodeEntry {
|
||||
return TagField::decode(bit_field_);
|
||||
}
|
||||
|
||||
static const char* const kEmptyNamePrefix;
|
||||
static const char* const kEmptyResourceName;
|
||||
static const char* const kEmptyBailoutReason;
|
||||
static const char* const kNoDeoptReason;
|
||||
@ -150,7 +146,6 @@ class CodeEntry {
|
||||
class BuiltinIdField : public BitField<Builtins::Name, 8, 24> {};
|
||||
|
||||
uint32_t bit_field_;
|
||||
const char* name_prefix_;
|
||||
const char* name_;
|
||||
const char* resource_name_;
|
||||
int line_number_;
|
||||
|
@ -37,9 +37,9 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
|
||||
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
|
||||
rec->start = code->address();
|
||||
rec->entry = NewCodeEntry(
|
||||
tag, GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
|
||||
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
|
||||
CpuProfileNode::kNoColumnNumberInfo, nullptr, code->InstructionStart());
|
||||
tag, GetFunctionName(name), CodeEntry::kEmptyResourceName,
|
||||
CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
|
||||
nullptr, code->InstructionStart());
|
||||
RecordInliningInfo(rec->entry, code);
|
||||
rec->size = code->ExecutableSize();
|
||||
DispatchCodeEvent(evt_rec);
|
||||
@ -51,9 +51,9 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
|
||||
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
|
||||
rec->start = code->address();
|
||||
rec->entry = NewCodeEntry(
|
||||
tag, GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
|
||||
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
|
||||
CpuProfileNode::kNoColumnNumberInfo, nullptr, code->InstructionStart());
|
||||
tag, GetFunctionName(name), CodeEntry::kEmptyResourceName,
|
||||
CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
|
||||
nullptr, code->InstructionStart());
|
||||
RecordInliningInfo(rec->entry, code);
|
||||
rec->size = code->ExecutableSize();
|
||||
DispatchCodeEvent(evt_rec);
|
||||
@ -66,11 +66,11 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
|
||||
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
|
||||
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
|
||||
rec->start = code->address();
|
||||
rec->entry = NewCodeEntry(
|
||||
tag, GetFunctionName(shared->DebugName()), CodeEntry::kEmptyNamePrefix,
|
||||
GetName(InferScriptName(script_name, shared)),
|
||||
CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
|
||||
nullptr, code->InstructionStart());
|
||||
rec->entry = NewCodeEntry(tag, GetFunctionName(shared->DebugName()),
|
||||
GetName(InferScriptName(script_name, shared)),
|
||||
CpuProfileNode::kNoLineNumberInfo,
|
||||
CpuProfileNode::kNoColumnNumberInfo, nullptr,
|
||||
code->InstructionStart());
|
||||
RecordInliningInfo(rec->entry, code);
|
||||
rec->entry->FillFunctionInfo(shared);
|
||||
rec->size = code->ExecutableSize();
|
||||
@ -100,10 +100,10 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
|
||||
line_table->SetPosition(it.code_offset(), line_number);
|
||||
}
|
||||
}
|
||||
rec->entry = NewCodeEntry(
|
||||
tag, GetFunctionName(shared->DebugName()), CodeEntry::kEmptyNamePrefix,
|
||||
GetName(InferScriptName(script_name, shared)), line, column,
|
||||
std::move(line_table), abstract_code->InstructionStart());
|
||||
rec->entry =
|
||||
NewCodeEntry(tag, GetFunctionName(shared->DebugName()),
|
||||
GetName(InferScriptName(script_name, shared)), line, column,
|
||||
std::move(line_table), abstract_code->InstructionStart());
|
||||
RecordInliningInfo(rec->entry, abstract_code);
|
||||
RecordDeoptInlinedFrames(rec->entry, abstract_code);
|
||||
rec->entry->FillFunctionInfo(shared);
|
||||
@ -121,10 +121,10 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
|
||||
// have names.
|
||||
const char* name_ptr =
|
||||
name.start() == nullptr ? "<anonymous>" : GetFunctionName(name.start());
|
||||
rec->entry = NewCodeEntry(
|
||||
tag, name_ptr, CodeEntry::kEmptyNamePrefix, CodeEntry::kEmptyResourceName,
|
||||
CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
|
||||
nullptr, code->instruction_start());
|
||||
rec->entry = NewCodeEntry(tag, name_ptr, CodeEntry::kEmptyResourceName,
|
||||
CpuProfileNode::kNoLineNumberInfo,
|
||||
CpuProfileNode::kNoColumnNumberInfo, nullptr,
|
||||
code->instruction_start());
|
||||
rec->size = code->instructions().length();
|
||||
DispatchCodeEvent(evt_rec);
|
||||
}
|
||||
@ -164,7 +164,7 @@ void ProfilerListener::GetterCallbackEvent(Name* name, Address entry_point) {
|
||||
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
|
||||
rec->start = entry_point;
|
||||
rec->entry =
|
||||
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetName(name), "get ");
|
||||
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetConsName("get ", name));
|
||||
rec->size = 1;
|
||||
DispatchCodeEvent(evt_rec);
|
||||
}
|
||||
@ -174,11 +174,11 @@ void ProfilerListener::RegExpCodeCreateEvent(AbstractCode* code,
|
||||
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
|
||||
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
|
||||
rec->start = code->address();
|
||||
rec->entry = NewCodeEntry(CodeEventListener::REG_EXP_TAG, GetName(source),
|
||||
"RegExp: ", CodeEntry::kEmptyResourceName,
|
||||
CpuProfileNode::kNoLineNumberInfo,
|
||||
CpuProfileNode::kNoColumnNumberInfo, nullptr,
|
||||
code->raw_instruction_start());
|
||||
rec->entry = NewCodeEntry(
|
||||
CodeEventListener::REG_EXP_TAG, GetConsName("RegExp: ", source),
|
||||
CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
|
||||
CpuProfileNode::kNoColumnNumberInfo, nullptr,
|
||||
code->raw_instruction_start());
|
||||
rec->size = code->ExecutableSize();
|
||||
DispatchCodeEvent(evt_rec);
|
||||
}
|
||||
@ -188,7 +188,7 @@ void ProfilerListener::SetterCallbackEvent(Name* name, Address entry_point) {
|
||||
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
|
||||
rec->start = entry_point;
|
||||
rec->entry =
|
||||
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetName(name), "set ");
|
||||
NewCodeEntry(CodeEventListener::CALLBACK_TAG, GetConsName("set ", name));
|
||||
rec->size = 1;
|
||||
DispatchCodeEvent(evt_rec);
|
||||
}
|
||||
@ -241,8 +241,7 @@ void ProfilerListener::RecordInliningInfo(CodeEntry* entry,
|
||||
|
||||
CodeEntry* inline_entry =
|
||||
new CodeEntry(entry->tag(), GetFunctionName(shared_info->DebugName()),
|
||||
CodeEntry::kEmptyNamePrefix, resource_name,
|
||||
CpuProfileNode::kNoLineNumberInfo,
|
||||
resource_name, CpuProfileNode::kNoLineNumberInfo,
|
||||
CpuProfileNode::kNoColumnNumberInfo, nullptr,
|
||||
code->InstructionStart());
|
||||
inline_entry->FillFunctionInfo(shared_info);
|
||||
@ -294,11 +293,10 @@ void ProfilerListener::RecordDeoptInlinedFrames(CodeEntry* entry,
|
||||
|
||||
CodeEntry* ProfilerListener::NewCodeEntry(
|
||||
CodeEventListener::LogEventsAndTags tag, const char* name,
|
||||
const char* name_prefix, const char* resource_name, int line_number,
|
||||
int column_number, std::unique_ptr<SourcePositionTable> line_info,
|
||||
Address instruction_start) {
|
||||
const char* resource_name, int line_number, int column_number,
|
||||
std::unique_ptr<SourcePositionTable> line_info, Address instruction_start) {
|
||||
std::unique_ptr<CodeEntry> code_entry = base::make_unique<CodeEntry>(
|
||||
tag, name, name_prefix, resource_name, line_number, column_number,
|
||||
tag, name, resource_name, line_number, column_number,
|
||||
std::move(line_info), instruction_start);
|
||||
CodeEntry* raw_code_entry = code_entry.get();
|
||||
code_entries_.push_back(std::move(code_entry));
|
||||
|
@ -54,7 +54,6 @@ class ProfilerListener : public CodeEventListener {
|
||||
|
||||
CodeEntry* NewCodeEntry(
|
||||
CodeEventListener::LogEventsAndTags tag, const char* name,
|
||||
const char* name_prefix = CodeEntry::kEmptyNamePrefix,
|
||||
const char* resource_name = CodeEntry::kEmptyResourceName,
|
||||
int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
|
||||
int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
|
||||
@ -67,6 +66,9 @@ class ProfilerListener : public CodeEventListener {
|
||||
const char* GetName(int args_count) {
|
||||
return function_and_resource_names_.GetName(args_count);
|
||||
}
|
||||
const char* GetConsName(const char* prefix, Name* name) {
|
||||
return function_and_resource_names_.GetConsName(prefix, name);
|
||||
}
|
||||
const char* GetFunctionName(Name* name) {
|
||||
return function_and_resource_names_.GetFunctionName(name);
|
||||
}
|
||||
|
@ -88,6 +88,25 @@ const char* StringsStorage::GetName(int index) {
|
||||
return GetFormatted("%d", index);
|
||||
}
|
||||
|
||||
const char* StringsStorage::GetConsName(const char* prefix, Name* name) {
|
||||
if (name->IsString()) {
|
||||
String* str = String::cast(name);
|
||||
int length = Min(FLAG_heap_snapshot_string_limit, str->length());
|
||||
int actual_length = 0;
|
||||
std::unique_ptr<char[]> data = str->ToCString(
|
||||
DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, 0, length, &actual_length);
|
||||
|
||||
int cons_length = actual_length + static_cast<int>(strlen(prefix)) + 1;
|
||||
char* cons_result = NewArray<char>(cons_length);
|
||||
snprintf(cons_result, cons_length, "%s%s", prefix, data.get());
|
||||
|
||||
return AddOrDisposeString(cons_result, cons_length);
|
||||
} else if (name->IsSymbol()) {
|
||||
return "<symbol>";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
const char* StringsStorage::GetFunctionName(Name* name) {
|
||||
return GetName(name);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ class StringsStorage {
|
||||
const char* GetVFormatted(const char* format, va_list args);
|
||||
const char* GetName(Name* name);
|
||||
const char* GetName(int index);
|
||||
const char* GetConsName(const char* prefix, Name* name);
|
||||
const char* GetFunctionName(Name* name);
|
||||
const char* GetFunctionName(const char* name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user