// Copyright 2016 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. #include "src/profiler/profiler-listener.h" #include #include "src/codegen/reloc-info.h" #include "src/codegen/source-position-table.h" #include "src/deoptimizer/deoptimizer.h" #include "src/handles/handles-inl.h" #include "src/objects/code-inl.h" #include "src/objects/objects-inl.h" #include "src/objects/script-inl.h" #include "src/objects/shared-function-info-inl.h" #include "src/objects/string-inl.h" #include "src/profiler/cpu-profiler.h" #include "src/profiler/profile-generator-inl.h" #include "src/utils/vector.h" #include "src/wasm/wasm-code-manager.h" namespace v8 { namespace internal { ProfilerListener::ProfilerListener(Isolate* isolate, CodeEventObserver* observer, CpuProfilingNamingMode naming_mode) : isolate_(isolate), observer_(observer), naming_mode_(naming_mode) {} ProfilerListener::~ProfilerListener() = default; void ProfilerListener::CodeCreateEvent(LogEventsAndTags tag, Handle code, const char* name) { CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; rec->instruction_start = code->InstructionStart(); rec->entry = new CodeEntry(tag, GetName(name), CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo, nullptr); rec->instruction_size = code->InstructionSize(); DispatchCodeEvent(evt_rec); } void ProfilerListener::CodeCreateEvent(LogEventsAndTags tag, Handle code, Handle name) { CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; rec->instruction_start = code->InstructionStart(); rec->entry = new CodeEntry(tag, GetName(*name), CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo, nullptr); rec->instruction_size = code->InstructionSize(); DispatchCodeEvent(evt_rec); } void ProfilerListener::CodeCreateEvent(LogEventsAndTags tag, Handle code, Handle shared, Handle script_name) { CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; rec->instruction_start = code->InstructionStart(); rec->entry = new CodeEntry(tag, GetName(shared->DebugName()), GetName(InferScriptName(*script_name, *shared)), CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo, nullptr); DCHECK(!code->IsCode()); rec->entry->FillFunctionInfo(*shared); rec->instruction_size = code->InstructionSize(); DispatchCodeEvent(evt_rec); } namespace { CodeEntry* GetOrInsertCachedEntry( std::unordered_set, CodeEntry::Hasher, CodeEntry::Equals>* entries, std::unique_ptr search_value) { auto it = entries->find(search_value); if (it != entries->end()) return it->get(); CodeEntry* ret = search_value.get(); entries->insert(std::move(search_value)); return ret; } } // namespace void ProfilerListener::CodeCreateEvent(LogEventsAndTags tag, Handle abstract_code, Handle shared, Handle script_name, int line, int column) { CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION); CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; rec->instruction_start = abstract_code->InstructionStart(); std::unique_ptr line_table; std::unordered_map> inline_stacks; std::unordered_set, CodeEntry::Hasher, CodeEntry::Equals> cached_inline_entries; bool is_shared_cross_origin = false; if (shared->script().IsScript()) { Handle