7#include "protos/perfetto/common/data_source_descriptor.gen.h"
8#include "protos/perfetto/config/chrome/v8_config.gen.h"
9#include "protos/perfetto/trace/chrome/v8.pbzero.h"
20#if V8_ENABLE_WEBASSEMBLY
31using ::perfetto::protos::gen::V8Config;
32using ::perfetto::protos::pbzero::InternedV8JsFunction;
33using ::perfetto::protos::pbzero::InternedV8JsScript;
34using ::perfetto::protos::pbzero::InternedV8String;
35using ::perfetto::protos::pbzero::TracePacket;
39 return InternedV8JsScript::TYPE_EVAL;
45 switch (script->type()) {
47 return InternedV8JsScript::TYPE_NATIVE;
49 return InternedV8JsScript::TYPE_EXTENSION;
51 return InternedV8JsScript::TYPE_NORMAL;
52#if V8_ENABLE_WEBASSEMBLY
53 case Script::Type::kWasm:
57 return InternedV8JsScript::TYPE_INSPECTOR;
64 return InternedV8JsFunction::KIND_NORMAL_FUNCTION;
66 return InternedV8JsFunction::KIND_MODULE;
68 return InternedV8JsFunction::KIND_ASYNC_MODULE;
70 return InternedV8JsFunction::KIND_BASE_CONSTRUCTOR;
72 return InternedV8JsFunction::KIND_DEFAULT_BASE_CONSTRUCTOR;
74 return InternedV8JsFunction::KIND_DEFAULT_DERIVED_CONSTRUCTOR;
76 return InternedV8JsFunction::KIND_DERIVED_CONSTRUCTOR;
78 return InternedV8JsFunction::KIND_GETTER_FUNCTION;
80 return InternedV8JsFunction::KIND_STATIC_GETTER_FUNCTION;
82 return InternedV8JsFunction::KIND_SETTER_FUNCTION;
84 return InternedV8JsFunction::KIND_STATIC_SETTER_FUNCTION;
86 return InternedV8JsFunction::KIND_ARROW_FUNCTION;
88 return InternedV8JsFunction::KIND_ASYNC_ARROW_FUNCTION;
90 return InternedV8JsFunction::KIND_ASYNC_FUNCTION;
92 return InternedV8JsFunction::KIND_ASYNC_CONCISE_METHOD;
94 return InternedV8JsFunction::KIND_STATIC_ASYNC_CONCISE_METHOD;
96 return InternedV8JsFunction::KIND_ASYNC_CONCISE_GENERATOR_METHOD;
98 return InternedV8JsFunction::KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD;
100 return InternedV8JsFunction::KIND_ASYNC_GENERATOR_FUNCTION;
102 return InternedV8JsFunction::KIND_GENERATOR_FUNCTION;
104 return InternedV8JsFunction::KIND_CONCISE_GENERATOR_METHOD;
106 return InternedV8JsFunction::KIND_STATIC_CONCISE_GENERATOR_METHOD;
108 return InternedV8JsFunction::KIND_CONCISE_METHOD;
110 return InternedV8JsFunction::KIND_STATIC_CONCISE_METHOD;
112 return InternedV8JsFunction::KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION;
114 return InternedV8JsFunction::KIND_CLASS_STATIC_INITIALIZER_FUNCTION;
116 return InternedV8JsFunction::KIND_INVALID;
119 return InternedV8JsFunction::KIND_UNKNOWN;
125 const CodeDataSource::TraceContext& context) {
126 if (
auto ds = context.GetDataSourceLocked(); ds) {
127 const V8Config& config = ds->config();
135 CodeDataSource::TraceContext::TracePacketHandle& packet) {
137 packet->AppendScatteredBytes(TracePacket::kInternedDataFieldNumber,
138 &ranges[0], ranges.size());
144 uint64_t iid = it->second;
150 isolate_proto->set_iid(iid);
151 isolate_proto->set_isolate_id(isolate.id());
153 isolate_proto->set_embedded_blob_code_start_address(
154 reinterpret_cast<uint64_t
>(isolate.embedded_blob_code()));
155 isolate_proto->set_embedded_blob_code_size(isolate.embedded_blob_code_size());
156 if (
auto* code_range = isolate.heap()->code_range(); code_range !=
nullptr) {
157 auto* v8_code_range = isolate_proto->set_code_range();
158 v8_code_range->set_base_address(code_range->base());
159 v8_code_range->set_size(code_range->size());
162 v8_code_range->set_is_process_wide(
true);
164 if (
auto* embedded_builtins_start = code_range->embedded_blob_code_copy();
165 embedded_builtins_start !=
nullptr) {
166 v8_code_range->set_embedded_blob_code_copy_start_address(
167 reinterpret_cast<uint64_t
>(embedded_builtins_start));
176 auto [it, was_inserted] =
scripts_.emplace(
180 uint64_t iid = it->second;
187 proto->set_script_id(script->id());
188 proto->set_type(GetJsScriptType(script));
189 if (IsString(script->name())) {
203 uint64_t v8_js_script_iid,
int line_num,
int column_num) {
210 v8_js_script_iid, info->is_toplevel(), info->StartPosition()},
212 const uint64_t iid = it->second;
218 function_proto->set_iid(iid);
219 function_proto->set_v8_js_function_name_iid(v8_js_function_name_iid);
220 function_proto->set_v8_js_script_iid(v8_js_script_iid);
221 function_proto->set_kind(GetJsFunctionKind(info->kind()));
222 int32_t start_position = info->StartPosition();
223 if (start_position >= 0) {
224 function_proto->set_byte_offset(
static_cast<uint32_t
>(start_position));
226 if (line_num > 0 && column_num > 0) {
227 function_proto->set_line(
static_cast<uint32_t
>(line_num));
228 function_proto->set_column(
static_cast<uint32_t
>(column_num));
234#if V8_ENABLE_WEBASSEMBLY
235uint64_t CodeDataSourceIncrementalState::InternWasmScript(
236 Isolate& isolate,
int script_id,
const std::string& url,
238 auto [it, was_inserted] =
scripts_.emplace(
241 uint64_t iid = it->second;
247 script->set_iid(iid);
248 script->set_script_id(script_id);
249 script->set_url(url);
251 base::Vector<const uint8_t> bytes_vec = native_module->
wire_bytes();
252 script->set_wire_bytes(bytes_vec.begin(), bytes_vec.size());
264 uint64_t iid = it->second;
270 v8_function_name->set_iid(iid);
271 it->first.WriteToProto(*v8_function_name);
277 perfetto::DataSourceDescriptor desc;
278 desc.set_name(
"dev.v8.code");
279 Base::Register(desc);
283 config_.ParseFromString(
args.config->v8_config_raw());
static int GetCurrentProcessId()
void Init(const CodeDataSource::TraceContext &context)
uint64_t next_function_iid() const
uint64_t InternJsFunctionName(Tagged< String > function_name)
uint64_t InternJsScript(Isolate &isolate, Tagged< Script > script)
void FlushInternedData(CodeDataSource::TraceContext::TracePacketHandle &packet)
bool log_script_sources() const
uint64_t InternIsolate(Isolate &isolate)
std::unordered_map< ScriptUniqueId, uint64_t, ScriptUniqueId::Hash > scripts_
std::unordered_map< Function, uint64_t, Function::Hash > functions_
uint64_t InternJsFunction(Isolate &isolate, DirectHandle< SharedFunctionInfo > info, uint64_t v8_js_script_iid, int line_num, int column_num)
uint64_t next_script_iid() const
std::unordered_map< int, uint64_t > isolates_
uint64_t next_isolate_iid() const
protozero::HeapBuffered< perfetto::protos::pbzero::InternedData > serialized_interned_data_
std::unordered_map< PerfettoV8String, uint64_t, PerfettoV8String::Hasher > js_function_names_
uint64_t next_js_function_name_iid() const
perfetto::protos::gen::V8Config config_
void OnSetup(const SetupArgs &) override
void OnStart(const StartArgs &) override
void OnStop(const StopArgs &) override
static IsolateGroup * current()
static void OnCodeDataSourceStop()
static void OnCodeDataSourceStart()
void WriteToProto(Proto &proto) const
static Handle< String > DebugName(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared)
base::Vector< const uint8_t > wire_bytes() const
PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(v8::internal::CodeDataSource, v8::internal::CodeDataSourceTraits)
base::Vector< const DirectHandle< Object > > args
Tagged(T object) -> Tagged< T >
@ kStaticConciseGeneratorMethod
@ kModuleWithTopLevelAwait
@ kDefaultDerivedConstructor
@ kClassStaticInitializerFunction
@ kConciseGeneratorMethod
@ kAsyncConciseGeneratorMethod
@ kClassMembersInitializerFunction
@ kDefaultBaseConstructor
@ kAsyncGeneratorFunction
@ kStaticAsyncConciseMethod
@ kStaticAsyncConciseGeneratorMethod
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)