/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/tracing/code-data-source.cc
297 строк
11 KB
Michaël Zasso
deps: update V8 to 14.6.202.33
24 апр 2026, 19:01
Не верифицирован
24 апр 2026, 19:01
f1e0b83
Код
Авторство
О чём код?
// Copyright 2024 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/tracing/code-data-source.h" #include "src/execution/isolate.h" #include "src/handles/handles.h" #include "src/heap/code-range.h" #include "src/objects/function-kind.h" #include "src/objects/script.h" #include "src/objects/shared-function-info.h" #include "src/objects/string-inl.h" #include "src/tracing/perfetto-logger.h" #include "src/tracing/perfetto-sdk.h" #include "src/tracing/perfetto-utils.h" #if V8_ENABLE_WEBASSEMBLY #include "src/wasm/wasm-code-manager.h" #endif // V8_ENABLE_WEBASSEMBLY PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(v8::internal::CodeDataSource, v8::internal::CodeDataSourceTraits); namespace v8 { namespace internal { namespace { using ::perfetto::protos::gen::V8Config; using ::perfetto::protos::pbzero::InternedV8JsFunction; using ::perfetto::protos::pbzero::InternedV8JsScript; using ::perfetto::protos::pbzero::InternedV8String; using ::perfetto::protos::pbzero::TracePacket; using ::protozero::ConstChars; InternedV8JsScript::Type GetJsScriptType(Tagged<Script> script) { if (script->compilation_type() == Script::CompilationType::kEval) { return InternedV8JsScript::TYPE_EVAL; } // TODO(carlscab): Camillo to extend the Script::Type enum. compilation_type // will no longer be needed. switch (script->type()) { case Script::Type::kNative: return InternedV8JsScript::TYPE_NATIVE; case Script::Type::kExtension: return InternedV8JsScript::TYPE_EXTENSION; case Script::Type::kNormal: return InternedV8JsScript::TYPE_NORMAL; #if V8_ENABLE_WEBASSEMBLY case Script::Type::kWasm: UNREACHABLE(); #endif // V8_ENABLE_WEBASSEMBLY case Script::Type::kInspector: return InternedV8JsScript::TYPE_INSPECTOR; } UNREACHABLE(); } InternedV8JsFunction::Kind GetJsFunctionKind(FunctionKind kind) { switch (kind) { case FunctionKind::kNormalFunction: return InternedV8JsFunction::KIND_NORMAL_FUNCTION; case FunctionKind::kModule: return InternedV8JsFunction::KIND_MODULE; case FunctionKind::kModuleWithTopLevelAwait: return InternedV8JsFunction::KIND_ASYNC_MODULE; case FunctionKind::kBaseConstructor: return InternedV8JsFunction::KIND_BASE_CONSTRUCTOR; case FunctionKind::kDefaultBaseConstructor: return InternedV8JsFunction::KIND_DEFAULT_BASE_CONSTRUCTOR; case FunctionKind::kDefaultDerivedConstructor: return InternedV8JsFunction::KIND_DEFAULT_DERIVED_CONSTRUCTOR; case FunctionKind::kDerivedConstructor: return InternedV8JsFunction::KIND_DERIVED_CONSTRUCTOR; case FunctionKind::kGetterFunction: return InternedV8JsFunction::KIND_GETTER_FUNCTION; case FunctionKind::kStaticGetterFunction: return InternedV8JsFunction::KIND_STATIC_GETTER_FUNCTION; case FunctionKind::kSetterFunction: return InternedV8JsFunction::KIND_SETTER_FUNCTION; case FunctionKind::kStaticSetterFunction: return InternedV8JsFunction::KIND_STATIC_SETTER_FUNCTION; case FunctionKind::kArrowFunction: return InternedV8JsFunction::KIND_ARROW_FUNCTION; case FunctionKind::kAsyncArrowFunction: return InternedV8JsFunction::KIND_ASYNC_ARROW_FUNCTION; case FunctionKind::kAsyncFunction: return InternedV8JsFunction::KIND_ASYNC_FUNCTION; case FunctionKind::kAsyncConciseMethod: return InternedV8JsFunction::KIND_ASYNC_CONCISE_METHOD; case FunctionKind::kStaticAsyncConciseMethod: return InternedV8JsFunction::KIND_STATIC_ASYNC_CONCISE_METHOD; case FunctionKind::kAsyncConciseGeneratorMethod: return InternedV8JsFunction::KIND_ASYNC_CONCISE_GENERATOR_METHOD; case FunctionKind::kStaticAsyncConciseGeneratorMethod: return InternedV8JsFunction::KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD; case FunctionKind::kAsyncGeneratorFunction: return InternedV8JsFunction::KIND_ASYNC_GENERATOR_FUNCTION; case FunctionKind::kGeneratorFunction: return InternedV8JsFunction::KIND_GENERATOR_FUNCTION; case FunctionKind::kConciseGeneratorMethod: return InternedV8JsFunction::KIND_CONCISE_GENERATOR_METHOD; case FunctionKind::kStaticConciseGeneratorMethod: return InternedV8JsFunction::KIND_STATIC_CONCISE_GENERATOR_METHOD; case FunctionKind::kConciseMethod: return InternedV8JsFunction::KIND_CONCISE_METHOD; case FunctionKind::kStaticConciseMethod: return InternedV8JsFunction::KIND_STATIC_CONCISE_METHOD; case FunctionKind::kClassMembersInitializerFunction: case FunctionKind::kClassMembersInitializerFunctionPrecededByStatic: return InternedV8JsFunction::KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION; case FunctionKind::kClassStaticInitializerFunction: case FunctionKind::kClassStaticInitializerFunctionPrecededByMember: return InternedV8JsFunction::KIND_CLASS_STATIC_INITIALIZER_FUNCTION; case FunctionKind::kInvalid: return InternedV8JsFunction::KIND_INVALID; } return InternedV8JsFunction::KIND_UNKNOWN; } } // namespace void CodeDataSourceIncrementalState::Init( const CodeDataSource::TraceContext& context) { if (auto ds = context.GetDataSourceLocked(); ds) { const V8Config& config = ds->config(); log_script_sources_ = config.log_script_sources(); log_instructions_ = config.log_instructions(); } initialized_ = true; } void CodeDataSourceIncrementalState::FlushInternedData( CodeDataSource::TraceContext::TracePacketHandle& packet) { auto ranges = serialized_interned_data_.GetRanges(); packet->AppendScatteredBytes(TracePacket::kInternedDataFieldNumber, &ranges[0], ranges.size()); serialized_interned_data_.Reset(); } uint64_t CodeDataSourceIncrementalState::InternIsolate(Isolate& isolate) { auto [it, was_inserted] = isolates_.emplace(isolate.id(), next_isolate_iid()); uint64_t iid = it->second; if (!was_inserted) { return iid; } auto* isolate_proto = serialized_interned_data_->add_v8_isolate(); isolate_proto->set_iid(iid); isolate_proto->set_isolate_id(isolate.id()); isolate_proto->set_pid(base::OS::GetCurrentProcessId()); isolate_proto->set_embedded_blob_code_start_address( reinterpret_cast<uint64_t>(isolate.embedded_blob_code())); isolate_proto->set_embedded_blob_code_size(isolate.embedded_blob_code_size()); if (auto* code_range = isolate.heap()->code_range(); code_range != nullptr) { auto* v8_code_range = isolate_proto->set_code_range(); v8_code_range->set_base_address(code_range->base()); v8_code_range->set_size(code_range->size()); if (code_range == IsolateGroup::current()->GetCodeRange()) { // FIXME(42204573): Belongs to isolate group, not process. v8_code_range->set_is_process_wide(true); } if (auto* embedded_builtins_start = code_range->embedded_blob_code_copy(); embedded_builtins_start != nullptr) { v8_code_range->set_embedded_blob_code_copy_start_address( reinterpret_cast<uint64_t>(embedded_builtins_start)); } } return iid; } uint64_t CodeDataSourceIncrementalState::InternJsScript(Isolate& isolate, Tagged<Script> script) { auto [it, was_inserted] = scripts_.emplace( CodeDataSourceIncrementalState::ScriptUniqueId{isolate.id(), script->id()}, next_script_iid()); uint64_t iid = it->second; if (!was_inserted) { return iid; } auto* proto = serialized_interned_data_->add_v8_js_script(); proto->set_iid(iid); proto->set_script_id(script->id()); proto->set_type(GetJsScriptType(script)); if (IsString(script->name())) { PerfettoV8String(Cast<String>(script->name())) .WriteToProto(*proto->set_name()); } if (log_script_sources() && IsString(script->source())) { PerfettoV8String(Cast<String>(script->source())) .WriteToProto(*proto->set_source()); } return iid; } uint64_t CodeDataSourceIncrementalState::InternJsFunction( Isolate& isolate, DirectHandle<SharedFunctionInfo> info, uint64_t v8_js_script_iid, int line_num, int column_num) { DirectHandle<String> function_name = SharedFunctionInfo::DebugName(&isolate, info); uint64_t v8_js_function_name_iid = InternJsFunctionName(*function_name); auto [it, was_inserted] = functions_.emplace( CodeDataSourceIncrementalState::Function{ v8_js_script_iid, info->is_toplevel(), info->StartPosition()}, next_function_iid()); const uint64_t iid = it->second; if (!was_inserted) { return iid; } auto* function_proto = serialized_interned_data_->add_v8_js_function(); function_proto->set_iid(iid); function_proto->set_v8_js_function_name_iid(v8_js_function_name_iid); function_proto->set_v8_js_script_iid(v8_js_script_iid); function_proto->set_kind(GetJsFunctionKind(info->kind())); int32_t start_position = info->StartPosition(); if (start_position >= 0) { function_proto->set_byte_offset(static_cast<uint32_t>(start_position)); } if (line_num > 0 && column_num > 0) { function_proto->set_line(static_cast<uint32_t>(line_num)); function_proto->set_column(static_cast<uint32_t>(column_num)); } return iid; } #if V8_ENABLE_WEBASSEMBLY uint64_t CodeDataSourceIncrementalState::InternWasmScript( Isolate& isolate, int script_id, std::string_view url, wasm::NativeModule* native_module) { auto [it, was_inserted] = scripts_.emplace( CodeDataSourceIncrementalState::ScriptUniqueId{isolate.id(), script_id}, next_script_iid()); uint64_t iid = it->second; if (!was_inserted) { return iid; } auto* script = serialized_interned_data_->add_v8_wasm_script(); script->set_iid(iid); script->set_script_id(script_id); script->set_url(ConstChars{url.data(), url.size()}); if (log_script_sources()) { base::Vector<const uint8_t> bytes_vec = native_module->wire_bytes(); script->set_wire_bytes(bytes_vec.begin(), bytes_vec.size()); // TODO(carlscab): Log script source if needed. } return iid; } #endif // V8_ENABLE_WEBASSEMBLY uint64_t CodeDataSourceIncrementalState::InternJsFunctionName( Tagged<String> function_name) { auto [it, was_inserted] = js_function_names_.emplace( PerfettoV8String(function_name), next_js_function_name_iid()); uint64_t iid = it->second; if (!was_inserted) { return iid; } auto* v8_function_name = serialized_interned_data_->add_v8_js_function_name(); v8_function_name->set_iid(iid); it->first.WriteToProto(*v8_function_name); return iid; } // static void CodeDataSource::Register() { perfetto::DataSourceDescriptor desc; desc.set_name("dev.v8.code"); Base::Register(desc); } void CodeDataSource::OnSetup(const SetupArgs& args) { config_.ParseFromString(args.config->v8_config_raw()); } void CodeDataSource::OnStart(const StartArgs&) { PerfettoLogger::OnCodeDataSourceStart(); } void CodeDataSource::OnStop(const StopArgs&) { PerfettoLogger::OnCodeDataSourceStop(); } } // namespace internal } // namespace v8