Merge "Add support for new v8 data source" into main
diff --git a/Android.bp b/Android.bp
index ee7f6b6..5c48dd4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2994,6 +2994,7 @@
     srcs: [
         "protos/perfetto/config/chrome/chrome_config.proto",
         "protos/perfetto/config/chrome/scenario_config.proto",
+        "protos/perfetto/config/chrome/v8_config.proto",
         "protos/perfetto/config/data_source_config.proto",
         "protos/perfetto/config/etw/etw_config.proto",
         "protos/perfetto/config/interceptor_config.proto",
@@ -3030,6 +3031,7 @@
     out: [
         "external/perfetto/protos/perfetto/config/chrome/chrome_config.gen.cc",
         "external/perfetto/protos/perfetto/config/chrome/scenario_config.gen.cc",
+        "external/perfetto/protos/perfetto/config/chrome/v8_config.gen.cc",
         "external/perfetto/protos/perfetto/config/data_source_config.gen.cc",
         "external/perfetto/protos/perfetto/config/etw/etw_config.gen.cc",
         "external/perfetto/protos/perfetto/config/interceptor_config.gen.cc",
@@ -3066,6 +3068,7 @@
     out: [
         "external/perfetto/protos/perfetto/config/chrome/chrome_config.gen.h",
         "external/perfetto/protos/perfetto/config/chrome/scenario_config.gen.h",
+        "external/perfetto/protos/perfetto/config/chrome/v8_config.gen.h",
         "external/perfetto/protos/perfetto/config/data_source_config.gen.h",
         "external/perfetto/protos/perfetto/config/etw/etw_config.gen.h",
         "external/perfetto/protos/perfetto/config/interceptor_config.gen.h",
@@ -3110,6 +3113,7 @@
         "protos/perfetto/config/android/surfaceflinger_transactions_config.proto",
         "protos/perfetto/config/chrome/chrome_config.proto",
         "protos/perfetto/config/chrome/scenario_config.proto",
+        "protos/perfetto/config/chrome/v8_config.proto",
         "protos/perfetto/config/data_source_config.proto",
         "protos/perfetto/config/etw/etw_config.proto",
         "protos/perfetto/config/ftrace/ftrace_config.proto",
@@ -3682,6 +3686,7 @@
     srcs: [
         "protos/perfetto/config/chrome/chrome_config.proto",
         "protos/perfetto/config/chrome/scenario_config.proto",
+        "protos/perfetto/config/chrome/v8_config.proto",
         "protos/perfetto/config/data_source_config.proto",
         "protos/perfetto/config/etw/etw_config.proto",
         "protos/perfetto/config/interceptor_config.proto",
@@ -3717,6 +3722,7 @@
     out: [
         "external/perfetto/protos/perfetto/config/chrome/chrome_config.pb.cc",
         "external/perfetto/protos/perfetto/config/chrome/scenario_config.pb.cc",
+        "external/perfetto/protos/perfetto/config/chrome/v8_config.pb.cc",
         "external/perfetto/protos/perfetto/config/data_source_config.pb.cc",
         "external/perfetto/protos/perfetto/config/etw/etw_config.pb.cc",
         "external/perfetto/protos/perfetto/config/interceptor_config.pb.cc",
@@ -3752,6 +3758,7 @@
     out: [
         "external/perfetto/protos/perfetto/config/chrome/chrome_config.pb.h",
         "external/perfetto/protos/perfetto/config/chrome/scenario_config.pb.h",
+        "external/perfetto/protos/perfetto/config/chrome/v8_config.pb.h",
         "external/perfetto/protos/perfetto/config/data_source_config.pb.h",
         "external/perfetto/protos/perfetto/config/etw/etw_config.pb.h",
         "external/perfetto/protos/perfetto/config/interceptor_config.pb.h",
@@ -4726,6 +4733,7 @@
     srcs: [
         "protos/perfetto/config/chrome/chrome_config.proto",
         "protos/perfetto/config/chrome/scenario_config.proto",
+        "protos/perfetto/config/chrome/v8_config.proto",
         "protos/perfetto/config/data_source_config.proto",
         "protos/perfetto/config/etw/etw_config.proto",
         "protos/perfetto/config/interceptor_config.proto",
@@ -4762,6 +4770,7 @@
     out: [
         "external/perfetto/protos/perfetto/config/chrome/chrome_config.pbzero.cc",
         "external/perfetto/protos/perfetto/config/chrome/scenario_config.pbzero.cc",
+        "external/perfetto/protos/perfetto/config/chrome/v8_config.pbzero.cc",
         "external/perfetto/protos/perfetto/config/data_source_config.pbzero.cc",
         "external/perfetto/protos/perfetto/config/etw/etw_config.pbzero.cc",
         "external/perfetto/protos/perfetto/config/interceptor_config.pbzero.cc",
@@ -4798,6 +4807,7 @@
     out: [
         "external/perfetto/protos/perfetto/config/chrome/chrome_config.pbzero.h",
         "external/perfetto/protos/perfetto/config/chrome/scenario_config.pbzero.h",
+        "external/perfetto/protos/perfetto/config/chrome/v8_config.pbzero.h",
         "external/perfetto/protos/perfetto/config/data_source_config.pbzero.h",
         "external/perfetto/protos/perfetto/config/etw/etw_config.pbzero.h",
         "external/perfetto/protos/perfetto/config/interceptor_config.pbzero.h",
@@ -5512,6 +5522,7 @@
         "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+        "protos/perfetto/trace/chrome/v8.proto",
     ],
 }
 
@@ -5530,6 +5541,7 @@
         "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.cc",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.cc",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.gen.cc",
+        "external/perfetto/protos/perfetto/trace/chrome/v8.gen.cc",
     ],
 }
 
@@ -5548,6 +5560,7 @@
         "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.h",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.h",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.gen.h",
+        "external/perfetto/protos/perfetto/trace/chrome/v8.gen.h",
     ],
     export_include_dirs: [
         ".",
@@ -5562,6 +5575,7 @@
         "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+        "protos/perfetto/trace/chrome/v8.proto",
     ],
 }
 
@@ -5579,6 +5593,7 @@
         "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.cc",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.cc",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.cc",
+        "external/perfetto/protos/perfetto/trace/chrome/v8.pb.cc",
     ],
 }
 
@@ -5596,6 +5611,7 @@
         "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.h",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.h",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.h",
+        "external/perfetto/protos/perfetto/trace/chrome/v8.pb.h",
     ],
     export_include_dirs: [
         ".",
@@ -5610,6 +5626,7 @@
         "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+        "protos/perfetto/trace/chrome/v8.proto",
     ],
 }
 
@@ -5628,6 +5645,7 @@
         "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc",
+        "external/perfetto/protos/perfetto/trace/chrome/v8.pbzero.cc",
     ],
 }
 
@@ -5646,6 +5664,7 @@
         "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.h",
         "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h",
+        "external/perfetto/protos/perfetto/trace/chrome/v8.pbzero.h",
     ],
     export_include_dirs: [
         ".",
@@ -5684,6 +5703,7 @@
         "protos/perfetto/config/android/surfaceflinger_transactions_config.proto",
         "protos/perfetto/config/chrome/chrome_config.proto",
         "protos/perfetto/config/chrome/scenario_config.proto",
+        "protos/perfetto/config/chrome/v8_config.proto",
         "protos/perfetto/config/data_source_config.proto",
         "protos/perfetto/config/etw/etw_config.proto",
         "protos/perfetto/config/ftrace/ftrace_config.proto",
@@ -5722,6 +5742,7 @@
         "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+        "protos/perfetto/trace/chrome/v8.proto",
         "protos/perfetto/trace/clock_snapshot.proto",
         "protos/perfetto/trace/etw/etw.proto",
         "protos/perfetto/trace/etw/etw_event.proto",
@@ -7053,6 +7074,7 @@
     srcs: [
         ":perfetto_protos_perfetto_common_cpp",
         ":perfetto_protos_perfetto_trace_android_cpp",
+        ":perfetto_protos_perfetto_trace_chrome_cpp",
         ":perfetto_protos_perfetto_trace_gpu_cpp",
         ":perfetto_protos_perfetto_trace_interned_data_cpp",
         ":perfetto_protos_perfetto_trace_profiling_cpp",
@@ -7074,6 +7096,7 @@
     srcs: [
         ":perfetto_protos_perfetto_common_cpp",
         ":perfetto_protos_perfetto_trace_android_cpp",
+        ":perfetto_protos_perfetto_trace_chrome_cpp",
         ":perfetto_protos_perfetto_trace_gpu_cpp",
         ":perfetto_protos_perfetto_trace_interned_data_cpp",
         ":perfetto_protos_perfetto_trace_profiling_cpp",
@@ -7107,6 +7130,7 @@
     srcs: [
         ":perfetto_protos_perfetto_common_lite",
         ":perfetto_protos_perfetto_trace_android_lite",
+        ":perfetto_protos_perfetto_trace_chrome_lite",
         ":perfetto_protos_perfetto_trace_gpu_lite",
         ":perfetto_protos_perfetto_trace_interned_data_lite",
         ":perfetto_protos_perfetto_trace_profiling_lite",
@@ -7127,6 +7151,7 @@
     srcs: [
         ":perfetto_protos_perfetto_common_lite",
         ":perfetto_protos_perfetto_trace_android_lite",
+        ":perfetto_protos_perfetto_trace_chrome_lite",
         ":perfetto_protos_perfetto_trace_gpu_lite",
         ":perfetto_protos_perfetto_trace_interned_data_lite",
         ":perfetto_protos_perfetto_trace_profiling_lite",
@@ -7159,6 +7184,7 @@
     srcs: [
         ":perfetto_protos_perfetto_common_zero",
         ":perfetto_protos_perfetto_trace_android_zero",
+        ":perfetto_protos_perfetto_trace_chrome_zero",
         ":perfetto_protos_perfetto_trace_gpu_zero",
         ":perfetto_protos_perfetto_trace_interned_data_zero",
         ":perfetto_protos_perfetto_trace_profiling_zero",
@@ -7180,6 +7206,7 @@
     srcs: [
         ":perfetto_protos_perfetto_common_zero",
         ":perfetto_protos_perfetto_trace_android_zero",
+        ":perfetto_protos_perfetto_trace_chrome_zero",
         ":perfetto_protos_perfetto_trace_gpu_zero",
         ":perfetto_protos_perfetto_trace_interned_data_zero",
         ":perfetto_protos_perfetto_trace_profiling_zero",
@@ -13123,6 +13150,7 @@
         "protos/perfetto/config/android/surfaceflinger_transactions_config.proto",
         "protos/perfetto/config/chrome/chrome_config.proto",
         "protos/perfetto/config/chrome/scenario_config.proto",
+        "protos/perfetto/config/chrome/v8_config.proto",
         "protos/perfetto/config/data_source_config.proto",
         "protos/perfetto/config/etw/etw_config.proto",
         "protos/perfetto/config/ftrace/ftrace_config.proto",
@@ -13161,6 +13189,7 @@
         "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+        "protos/perfetto/trace/chrome/v8.proto",
         "protos/perfetto/trace/clock_snapshot.proto",
         "protos/perfetto/trace/etw/etw.proto",
         "protos/perfetto/trace/etw/etw_event.proto",
diff --git a/BUILD b/BUILD
index 66c6448..23b3585 100644
--- a/BUILD
+++ b/BUILD
@@ -3828,6 +3828,7 @@
     srcs = [
         "protos/perfetto/config/chrome/chrome_config.proto",
         "protos/perfetto/config/chrome/scenario_config.proto",
+        "protos/perfetto/config/chrome/v8_config.proto",
         "protos/perfetto/config/data_source_config.proto",
         "protos/perfetto/config/etw/etw_config.proto",
         "protos/perfetto/config/interceptor_config.proto",
@@ -4325,6 +4326,7 @@
         "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_metadata.proto",
         "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+        "protos/perfetto/trace/chrome/v8.proto",
     ],
     visibility = [
         PERFETTO_CONFIG.proto_library_visibility,
@@ -4514,6 +4516,7 @@
     deps = [
         ":protos_perfetto_common_protos",
         ":protos_perfetto_trace_android_protos",
+        ":protos_perfetto_trace_chrome_protos",
         ":protos_perfetto_trace_gpu_protos",
         ":protos_perfetto_trace_profiling_protos",
         ":protos_perfetto_trace_track_event_protos",
@@ -4526,6 +4529,7 @@
     deps = [
         ":protos_perfetto_common_zero",
         ":protos_perfetto_trace_android_zero",
+        ":protos_perfetto_trace_chrome_zero",
         ":protos_perfetto_trace_gpu_zero",
         ":protos_perfetto_trace_interned_data_protos",
         ":protos_perfetto_trace_profiling_zero",
diff --git a/protos/perfetto/config/BUILD.gn b/protos/perfetto/config/BUILD.gn
index 3b325dc..22d052a 100644
--- a/protos/perfetto/config/BUILD.gn
+++ b/protos/perfetto/config/BUILD.gn
@@ -38,6 +38,7 @@
   sources = [
     "chrome/chrome_config.proto",
     "chrome/scenario_config.proto",
+    "chrome/v8_config.proto",
     "data_source_config.proto",
     "etw/etw_config.proto",
     "interceptor_config.proto",
diff --git a/protos/perfetto/config/chrome/v8_config.proto b/protos/perfetto/config/chrome/v8_config.proto
new file mode 100644
index 0000000..bcb0e5b
--- /dev/null
+++ b/protos/perfetto/config/chrome/v8_config.proto
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+syntax = "proto2";
+
+package perfetto.protos;
+
+message V8Config {
+  // Whether to log the actual content of scripts (e.g. content of the JS file
+  // that was compiled to generate code).
+  // ATTENTION: This could considerably increase the size of the resuling trace
+  //            file.
+  optional bool log_script_sources = 1;
+  // Whether to log the generated code for jitted functions (machine code or
+  // bytecode).
+  // ATTENTION: This could considerably increase the size of the resuling trace
+  //            file.
+  optional bool log_instructions = 2;
+}
diff --git a/protos/perfetto/config/data_source_config.proto b/protos/perfetto/config/data_source_config.proto
index 7af57dc..3970110 100644
--- a/protos/perfetto/config/data_source_config.proto
+++ b/protos/perfetto/config/data_source_config.proto
@@ -28,6 +28,7 @@
 import "protos/perfetto/config/android/surfaceflinger_layers_config.proto";
 import "protos/perfetto/config/android/surfaceflinger_transactions_config.proto";
 import "protos/perfetto/config/chrome/chrome_config.proto";
+import "protos/perfetto/config/chrome/v8_config.proto";
 import "protos/perfetto/config/etw/etw_config.proto";
 import "protos/perfetto/config/ftrace/ftrace_config.proto";
 import "protos/perfetto/config/gpu/gpu_counter_config.proto";
@@ -154,6 +155,9 @@
   // C++ class for it so it can pass around plain C++ objets.
   optional ChromeConfig chrome_config = 101;
 
+  // Data source name: code.v8.dev
+  optional V8Config v8_config = 127 [lazy = true];
+
   // If an interceptor is specified here, packets for this data source will be
   // rerouted to the interceptor instead of the main trace buffer. This can be
   // used, for example, to write trace data into ETW or for logging trace points
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index cdf76da..ef0330e 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -645,6 +645,23 @@
 
 // End of protos/perfetto/config/chrome/chrome_config.proto
 
+// Begin of protos/perfetto/config/chrome/v8_config.proto
+
+message V8Config {
+  // Whether to log the actual content of scripts (e.g. content of the JS file
+  // that was compiled to generate code).
+  // ATTENTION: This could considerably increase the size of the resuling trace
+  //            file.
+  optional bool log_script_sources = 1;
+  // Whether to log the generated code for jitted functions (machine code or
+  // bytecode).
+  // ATTENTION: This could considerably increase the size of the resuling trace
+  //            file.
+  optional bool log_instructions = 2;
+}
+
+// End of protos/perfetto/config/chrome/v8_config.proto
+
 // Begin of protos/perfetto/config/etw/etw_config.proto
 
 // Proto definition based on the struct _EVENT_TRACE_PROPERTIES definition
@@ -3112,6 +3129,9 @@
   // C++ class for it so it can pass around plain C++ objets.
   optional ChromeConfig chrome_config = 101;
 
+  // Data source name: code.v8.dev
+  optional V8Config v8_config = 127 [lazy = true];
+
   // If an interceptor is specified here, packets for this data source will be
   // rerouted to the interceptor instead of the main trace buffer. This can be
   // used, for example, to write trace data into ETW or for logging trace points
diff --git a/protos/perfetto/trace/chrome/BUILD.gn b/protos/perfetto/trace/chrome/BUILD.gn
index 2cad830..0df6b88 100644
--- a/protos/perfetto/trace/chrome/BUILD.gn
+++ b/protos/perfetto/trace/chrome/BUILD.gn
@@ -19,6 +19,7 @@
     "chrome_benchmark_metadata.proto",
     "chrome_metadata.proto",
     "chrome_trace_event.proto",
+    "v8.proto",
   ]
 }
 
diff --git a/protos/perfetto/trace/chrome/v8.proto b/protos/perfetto/trace/chrome/v8.proto
new file mode 100644
index 0000000..fdd551e
--- /dev/null
+++ b/protos/perfetto/trace/chrome/v8.proto
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+syntax = "proto2";
+
+package perfetto.protos;
+
+// These are the protos for the V8 data source.
+//
+// All events are associated to a V8 isolate instance. There can be multiple
+// instances associated to a given thread, although this is rare.
+//
+// Generated code in V8 is allocated in the V8 heap (in a special executeable
+// section), this means that code can be garbage collected (when no longer used)
+// or can be moved around (e.g. during heap compactation). This means that a
+// given callsite might correspond to function `A` at one point in time and to
+// function `B` later on.
+// In addition V8 code has various levels of optimization, so a function might
+// have multiple associated code snippets.
+//
+// V8 does not track code deletion, so we have to indirectly infer it by
+// detecting code overlaps, if a newer code creation event overlaps with older
+// code we need to asume that the old code was deleted. Code moves are logged,
+// and there is an event to track those.
+
+// Strings used by V8 can have different encodings, instead of coverting to a
+// common encoding (e.g. UTF-8) on device is expensive. Instead we send the
+// "raw" string and do the convestion at trace ingestion time.
+//
+// ATTENTION: There is some overhead in using a message (as opossed to having
+// the `oneof encoded_string`` direcly embedded in the message), so use this
+// message in places were these extra bytes don't matter that much.
+// Next id: 5
+message V8String {
+  oneof encoded_string {
+    // ISO/IEC 8859-1:1998 encoding aka latin1
+    // https://en.wikipedia.org/wiki/ISO/IEC_8859-1
+    bytes latin1 = 1;
+    // UTF-16 Little Endian Encoding
+    bytes utf16_le = 2;
+    // UTF-16 Big Endian Encoding
+    bytes utf16_be = 3;
+  }
+}
+
+// Interned version of V8String
+message InternedV8String {
+  optional uint64 iid = 1;
+  // We inline the fields in V8String here to save some bytes in the serialized
+  // proto format. Interning is about saving bytes so this makes sense here.
+  oneof encoded_string {
+    // ISO/IEC 8859-1:1998 encoding aka latin1
+    // https://en.wikipedia.org/wiki/ISO/IEC_8859-1
+    bytes latin1 = 2;
+    // UTF-16 Little Endian Encoding
+    bytes utf16_le = 3;
+    // UTF-16 Big Endian Encoding
+    bytes utf16_be = 4;
+  }
+}
+
+// Represents a script that was compiled to generate code. Some V8 code is
+// generated out of scripts and will reference a V8Script other types of code
+// will not (e.g. builtins).
+message InternedV8JsScript {
+  optional uint64 iid = 1;
+  // Unique in a given isolate
+  optional int32 script_id = 2;
+
+  enum Type {
+    TYPE_UNKNOWN = 0;
+    TYPE_NORMAL = 1;
+    TYPE_EVAL = 2;
+    TYPE_MODULE = 3;
+    TYPE_NATIVE = 4;
+    TYPE_EXTENSION = 5;
+    TYPE_INSPECTOR = 6;
+  }
+
+  optional Type type = 3;
+  optional V8String name = 4;
+  // Actual source of the script
+  optional V8String source = 5;
+}
+
+message InternedV8WasmScript {
+  optional uint64 iid = 1;
+  // Unique in a given isolate
+  optional int32 script_id = 2;
+
+  optional string url = 3;
+}
+
+message InternedV8JsFunction {
+  enum Kind {
+    KIND_UNKNOWN = 0;
+    KIND_NORMAL_FUNCTION = 1;
+    KIND_MODULE = 2;
+    KIND_ASYNC_MODULE = 3;
+    KIND_BASE_CONSTRUCTOR = 4;
+    KIND_DEFAULT_BASE_CONSTRUCTOR = 5;
+    KIND_DEFAULT_DERIVED_CONSTRUCTOR = 6;
+    KIND_DERIVED_CONSTRUCTOR = 7;
+    KIND_GETTER_FUNCTION = 8;
+    KIND_STATIC_GETTER_FUNCTION = 9;
+    KIND_SETTER_FUNCTION = 10;
+    KIND_STATIC_SETTER_FUNCTION = 11;
+    KIND_ARROW_FUNCTION = 12;
+    KIND_ASYNC_ARROW_FUNCTION = 13;
+    KIND_ASYNC_FUNCTION = 14;
+    KIND_ASYNC_CONCISE_METHOD = 15;
+    KIND_STATIC_ASYNC_CONCISE_METHOD = 16;
+    KIND_ASYNC_CONCISE_GENERATOR_METHOD = 17;
+    KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD = 18;
+    KIND_ASYNC_GENERATOR_FUNCTION = 19;
+    KIND_GENERATOR_FUNCTION = 20;
+    KIND_CONCISE_GENERATOR_METHOD = 21;
+    KIND_STATIC_CONCISE_GENERATOR_METHOD = 22;
+    KIND_CONCISE_METHOD = 23;
+    KIND_STATIC_CONCISE_METHOD = 24;
+    KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION = 25;
+    KIND_CLASS_STATIC_INITIALIZER_FUNCTION = 26;
+    KIND_INVALID = 27;
+  }
+  optional uint64 iid = 1;
+  optional uint64 v8_js_function_name_iid = 2;
+  optional uint64 v8_js_script_iid = 3;
+
+  optional bool is_toplevel = 4;
+  optional Kind kind = 5;
+
+  // Where in the script source this function is defined. This is counted in
+  // bytes not characters.
+  optional uint32 byte_offset = 6;
+}
+
+// A V8 Isolate instance. A V8 Isolate represents an isolated instance of the V8
+// engine.
+message InternedV8Isolate {
+  optional uint64 iid = 1;
+
+  optional uint32 pid = 2;
+
+  // Process unique isolate id.
+  optional int32 isolate_id = 3;
+
+  // A code range is a virtual memory cage that may contain executable code.
+  // Depending on the Isolate settings the Isolate might have one or not.
+  // See:
+  // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/heap/code-range.h
+  // If the isolate defines code range this will be tracked here.
+  message CodeRange {
+    optional uint64 base_address = 1;
+    optional uint64 size = 2;
+    // Used when short builtin calls are enabled, where embedded builtins are
+    // copied into the CodeRange so calls can be nearer.
+    optional uint64 embedded_blob_code_copy_start_address = 3;
+    // Whether this code range is shared with other Isolates in the same process
+    optional bool is_process_wide = 4;
+  }
+  optional CodeRange code_range = 4;
+  // The embedded blob holds code for built in functions that are precompiled in
+  // the V8 library.
+  optional uint64 embedded_blob_code_start_address = 5;
+  optional uint64 embedded_blob_code_size = 6;
+}
+
+message V8JsCode {
+  enum Tier {
+    TIER_UNKNOWN = 0;
+    TIER_IGNITION = 1;
+    TIER_SPARKPLUG = 2;
+    TIER_MAGLEV = 3;
+    TIER_TURBOSHAFT = 4;
+    TIER_TURBOFAN = 5;
+  }
+  optional uint64 v8_isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional uint64 v8_js_function_iid = 3;
+  optional Tier tier = 4;
+
+  optional uint64 instruction_start = 5;
+  optional uint64 instruction_size_bytes = 6;
+  oneof instructions {
+    bytes machine_code = 7;
+    bytes bytecode = 8;
+  }
+}
+
+message V8InternalCode {
+  enum Type {
+    TYPE_UNKNOWN = 0;
+    TYPE_BYTECODE_HANDLER = 1;
+    TYPE_FOR_TESTING = 2;
+    TYPE_BUILTIN = 3;
+    TYPE_WASM_FUNCTION = 4;
+    TYPE_WASM_TO_CAPI_FUNCTION = 5;
+    TYPE_WASM_TO_JS_FUNCTION = 6;
+    TYPE_JS_TO_WASM_FUNCTION = 7;
+    TYPE_JS_TO_JS_FUNCTION = 8;
+    TYPE_C_WASM_ENTRY = 9;
+  }
+  optional uint64 v8_isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional string name = 3;
+  optional Type type = 4;
+  optional int32 builtin_id = 5;
+
+  optional uint64 instruction_start = 6;
+  optional uint64 instruction_size_bytes = 7;
+  optional bytes machine_code = 8;
+}
+
+message V8WasmCode {
+  enum Tier {
+    TIER_UNKNOWN = 0;
+    TIER_LIFTOFF = 1;
+    TIER_TURBOFAN = 2;
+  }
+  optional uint64 v8_isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional uint64 v8_wasm_script_iid = 3;
+  optional string function_name = 4;
+
+  optional Tier tier = 5;
+  optional int32 code_offset_in_module = 6;
+
+  optional uint64 instruction_start = 7;
+  optional uint64 instruction_size_bytes = 8;
+  optional bytes machine_code = 9;
+}
+
+message V8RegExpCode {
+  optional uint64 v8_isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional V8String pattern = 3;
+
+  optional uint64 instruction_start = 4;
+  optional uint64 instruction_size_bytes = 5;
+  optional bytes machine_code = 6;
+}
+
+// Move event for V8 code (JS / Wasm / Internal / Regexp) that was relocated in
+// memory by V8's GC.
+message V8CodeMove {
+  optional uint64 isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional uint64 from_instruction_start_address = 3;
+  optional uint64 to_instruction_start_address = 4;
+  optional uint64 instruction_size_bytes = 5;
+  oneof to_instructions {
+    bytes to_machine_code = 6;
+    bytes to_bytecode = 7;
+  }
+}
+
+message V8CodeDefaults {
+  optional uint32 tid = 1;
+}
\ No newline at end of file
diff --git a/protos/perfetto/trace/interned_data/BUILD.gn b/protos/perfetto/trace/interned_data/BUILD.gn
index 66436c5..f6f87d3 100644
--- a/protos/perfetto/trace/interned_data/BUILD.gn
+++ b/protos/perfetto/trace/interned_data/BUILD.gn
@@ -18,6 +18,7 @@
   sources = [ "interned_data.proto" ]
   deps = [
     "../android:@TYPE@",
+    "../chrome:@TYPE@",
     "../gpu:@TYPE@",
     "../profiling:@TYPE@",
     "../track_event:@TYPE@",
diff --git a/protos/perfetto/trace/interned_data/interned_data.proto b/protos/perfetto/trace/interned_data/interned_data.proto
index e7517ce..88e1939 100644
--- a/protos/perfetto/trace/interned_data/interned_data.proto
+++ b/protos/perfetto/trace/interned_data/interned_data.proto
@@ -17,6 +17,7 @@
 syntax = "proto2";
 
 import "protos/perfetto/trace/android/network_trace.proto";
+import "protos/perfetto/trace/chrome/v8.proto";
 import "protos/perfetto/trace/gpu/gpu_render_stage_event.proto";
 import "protos/perfetto/trace/track_event/chrome_histogram_sample.proto";
 import "protos/perfetto/trace/track_event/debug_annotation.proto";
@@ -54,7 +55,7 @@
 // emitted proactively in advance of referring to them in later packets.
 //
 // Next reserved id: 8 (up to 15).
-// Next id: 31.
+// Next id: 36.
 message InternedData {
   // TODO(eseckler): Replace iid fields inside interned messages with
   // map<iid, message> type fields in InternedData.
@@ -116,4 +117,19 @@
 
   // Interned packet context for android.network_packets.
   repeated NetworkPacketContext packet_context = 30;
+
+  // Interned name of a js function. We only intern js functions as there is a
+  // lot of duplication for them, but less so for other strings in the V8 data
+  // source.
+  repeated InternedV8String v8_js_function_name = 31;
+  // Js functions can be emitted multiple times for various compilation tiers,
+  // so it makes sense to deduplicate all this.
+  repeated InternedV8JsFunction v8_js_function = 32;
+  // Interned JS script (there is one associated with each JS function)
+  repeated InternedV8JsScript v8_js_script = 33;
+  // Interned Wasm script (there is one associated with each Wasm function)
+  repeated InternedV8WasmScript v8_wasm_script = 34;
+  // Every V8 event is associated with an isolate, intern the isolate to remove
+  // duplication.
+  repeated InternedV8Isolate v8_isolate = 35;
 }
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 9aa2e31..be48293 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -645,6 +645,23 @@
 
 // End of protos/perfetto/config/chrome/chrome_config.proto
 
+// Begin of protos/perfetto/config/chrome/v8_config.proto
+
+message V8Config {
+  // Whether to log the actual content of scripts (e.g. content of the JS file
+  // that was compiled to generate code).
+  // ATTENTION: This could considerably increase the size of the resuling trace
+  //            file.
+  optional bool log_script_sources = 1;
+  // Whether to log the generated code for jitted functions (machine code or
+  // bytecode).
+  // ATTENTION: This could considerably increase the size of the resuling trace
+  //            file.
+  optional bool log_instructions = 2;
+}
+
+// End of protos/perfetto/config/chrome/v8_config.proto
+
 // Begin of protos/perfetto/config/etw/etw_config.proto
 
 // Proto definition based on the struct _EVENT_TRACE_PROPERTIES definition
@@ -3112,6 +3129,9 @@
   // C++ class for it so it can pass around plain C++ objets.
   optional ChromeConfig chrome_config = 101;
 
+  // Data source name: code.v8.dev
+  optional V8Config v8_config = 127 [lazy = true];
+
   // If an interceptor is specified here, packets for this data source will be
   // rerouted to the interceptor instead of the main trace buffer. This can be
   // used, for example, to write trace data into ETW or for logging trace points
@@ -5576,6 +5596,262 @@
 
 // End of protos/perfetto/trace/chrome/chrome_trace_event.proto
 
+// Begin of protos/perfetto/trace/chrome/v8.proto
+
+// These are the protos for the V8 data source.
+//
+// All events are associated to a V8 isolate instance. There can be multiple
+// instances associated to a given thread, although this is rare.
+//
+// Generated code in V8 is allocated in the V8 heap (in a special executeable
+// section), this means that code can be garbage collected (when no longer used)
+// or can be moved around (e.g. during heap compactation). This means that a
+// given callsite might correspond to function `A` at one point in time and to
+// function `B` later on.
+// In addition V8 code has various levels of optimization, so a function might
+// have multiple associated code snippets.
+//
+// V8 does not track code deletion, so we have to indirectly infer it by
+// detecting code overlaps, if a newer code creation event overlaps with older
+// code we need to asume that the old code was deleted. Code moves are logged,
+// and there is an event to track those.
+
+// Strings used by V8 can have different encodings, instead of coverting to a
+// common encoding (e.g. UTF-8) on device is expensive. Instead we send the
+// "raw" string and do the convestion at trace ingestion time.
+//
+// ATTENTION: There is some overhead in using a message (as opossed to having
+// the `oneof encoded_string`` direcly embedded in the message), so use this
+// message in places were these extra bytes don't matter that much.
+// Next id: 5
+message V8String {
+  oneof encoded_string {
+    // ISO/IEC 8859-1:1998 encoding aka latin1
+    // https://en.wikipedia.org/wiki/ISO/IEC_8859-1
+    bytes latin1 = 1;
+    // UTF-16 Little Endian Encoding
+    bytes utf16_le = 2;
+    // UTF-16 Big Endian Encoding
+    bytes utf16_be = 3;
+  }
+}
+
+// Interned version of V8String
+message InternedV8String {
+  optional uint64 iid = 1;
+  // We inline the fields in V8String here to save some bytes in the serialized
+  // proto format. Interning is about saving bytes so this makes sense here.
+  oneof encoded_string {
+    // ISO/IEC 8859-1:1998 encoding aka latin1
+    // https://en.wikipedia.org/wiki/ISO/IEC_8859-1
+    bytes latin1 = 2;
+    // UTF-16 Little Endian Encoding
+    bytes utf16_le = 3;
+    // UTF-16 Big Endian Encoding
+    bytes utf16_be = 4;
+  }
+}
+
+// Represents a script that was compiled to generate code. Some V8 code is
+// generated out of scripts and will reference a V8Script other types of code
+// will not (e.g. builtins).
+message InternedV8JsScript {
+  optional uint64 iid = 1;
+  // Unique in a given isolate
+  optional int32 script_id = 2;
+
+  enum Type {
+    TYPE_UNKNOWN = 0;
+    TYPE_NORMAL = 1;
+    TYPE_EVAL = 2;
+    TYPE_MODULE = 3;
+    TYPE_NATIVE = 4;
+    TYPE_EXTENSION = 5;
+    TYPE_INSPECTOR = 6;
+  }
+
+  optional Type type = 3;
+  optional V8String name = 4;
+  // Actual source of the script
+  optional V8String source = 5;
+}
+
+message InternedV8WasmScript {
+  optional uint64 iid = 1;
+  // Unique in a given isolate
+  optional int32 script_id = 2;
+
+  optional string url = 3;
+}
+
+message InternedV8JsFunction {
+  enum Kind {
+    KIND_UNKNOWN = 0;
+    KIND_NORMAL_FUNCTION = 1;
+    KIND_MODULE = 2;
+    KIND_ASYNC_MODULE = 3;
+    KIND_BASE_CONSTRUCTOR = 4;
+    KIND_DEFAULT_BASE_CONSTRUCTOR = 5;
+    KIND_DEFAULT_DERIVED_CONSTRUCTOR = 6;
+    KIND_DERIVED_CONSTRUCTOR = 7;
+    KIND_GETTER_FUNCTION = 8;
+    KIND_STATIC_GETTER_FUNCTION = 9;
+    KIND_SETTER_FUNCTION = 10;
+    KIND_STATIC_SETTER_FUNCTION = 11;
+    KIND_ARROW_FUNCTION = 12;
+    KIND_ASYNC_ARROW_FUNCTION = 13;
+    KIND_ASYNC_FUNCTION = 14;
+    KIND_ASYNC_CONCISE_METHOD = 15;
+    KIND_STATIC_ASYNC_CONCISE_METHOD = 16;
+    KIND_ASYNC_CONCISE_GENERATOR_METHOD = 17;
+    KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD = 18;
+    KIND_ASYNC_GENERATOR_FUNCTION = 19;
+    KIND_GENERATOR_FUNCTION = 20;
+    KIND_CONCISE_GENERATOR_METHOD = 21;
+    KIND_STATIC_CONCISE_GENERATOR_METHOD = 22;
+    KIND_CONCISE_METHOD = 23;
+    KIND_STATIC_CONCISE_METHOD = 24;
+    KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION = 25;
+    KIND_CLASS_STATIC_INITIALIZER_FUNCTION = 26;
+    KIND_INVALID = 27;
+  }
+  optional uint64 iid = 1;
+  optional uint64 v8_js_function_name_iid = 2;
+  optional uint64 v8_js_script_iid = 3;
+
+  optional bool is_toplevel = 4;
+  optional Kind kind = 5;
+
+  // Where in the script source this function is defined. This is counted in
+  // bytes not characters.
+  optional uint32 byte_offset = 6;
+}
+
+// A V8 Isolate instance. A V8 Isolate represents an isolated instance of the V8
+// engine.
+message InternedV8Isolate {
+  optional uint64 iid = 1;
+
+  optional uint32 pid = 2;
+
+  // Process unique isolate id.
+  optional int32 isolate_id = 3;
+
+  // A code range is a virtual memory cage that may contain executable code.
+  // Depending on the Isolate settings the Isolate might have one or not.
+  // See:
+  // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/heap/code-range.h
+  // If the isolate defines code range this will be tracked here.
+  message CodeRange {
+    optional uint64 base_address = 1;
+    optional uint64 size = 2;
+    // Used when short builtin calls are enabled, where embedded builtins are
+    // copied into the CodeRange so calls can be nearer.
+    optional uint64 embedded_blob_code_copy_start_address = 3;
+    // Whether this code range is shared with other Isolates in the same process
+    optional bool is_process_wide = 4;
+  }
+  optional CodeRange code_range = 4;
+  // The embedded blob holds code for built in functions that are precompiled in
+  // the V8 library.
+  optional uint64 embedded_blob_code_start_address = 5;
+  optional uint64 embedded_blob_code_size = 6;
+}
+
+message V8JsCode {
+  enum Tier {
+    TIER_UNKNOWN = 0;
+    TIER_IGNITION = 1;
+    TIER_SPARKPLUG = 2;
+    TIER_MAGLEV = 3;
+    TIER_TURBOSHAFT = 4;
+    TIER_TURBOFAN = 5;
+  }
+  optional uint64 v8_isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional uint64 v8_js_function_iid = 3;
+  optional Tier tier = 4;
+
+  optional uint64 instruction_start = 5;
+  optional uint64 instruction_size_bytes = 6;
+  oneof instructions {
+    bytes machine_code = 7;
+    bytes bytecode = 8;
+  }
+}
+
+message V8InternalCode {
+  enum Type {
+    TYPE_UNKNOWN = 0;
+    TYPE_BYTECODE_HANDLER = 1;
+    TYPE_FOR_TESTING = 2;
+    TYPE_BUILTIN = 3;
+    TYPE_WASM_FUNCTION = 4;
+    TYPE_WASM_TO_CAPI_FUNCTION = 5;
+    TYPE_WASM_TO_JS_FUNCTION = 6;
+    TYPE_JS_TO_WASM_FUNCTION = 7;
+    TYPE_JS_TO_JS_FUNCTION = 8;
+    TYPE_C_WASM_ENTRY = 9;
+  }
+  optional uint64 v8_isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional string name = 3;
+  optional Type type = 4;
+  optional int32 builtin_id = 5;
+
+  optional uint64 instruction_start = 6;
+  optional uint64 instruction_size_bytes = 7;
+  optional bytes machine_code = 8;
+}
+
+message V8WasmCode {
+  enum Tier {
+    TIER_UNKNOWN = 0;
+    TIER_LIFTOFF = 1;
+    TIER_TURBOFAN = 2;
+  }
+  optional uint64 v8_isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional uint64 v8_wasm_script_iid = 3;
+  optional string function_name = 4;
+
+  optional Tier tier = 5;
+  optional int32 code_offset_in_module = 6;
+
+  optional uint64 instruction_start = 7;
+  optional uint64 instruction_size_bytes = 8;
+  optional bytes machine_code = 9;
+}
+
+message V8RegExpCode {
+  optional uint64 v8_isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional V8String pattern = 3;
+
+  optional uint64 instruction_start = 4;
+  optional uint64 instruction_size_bytes = 5;
+  optional bytes machine_code = 6;
+}
+
+// Move event for V8 code (JS / Wasm / Internal / Regexp) that was relocated in
+// memory by V8's GC.
+message V8CodeMove {
+  optional uint64 isolate_iid = 1;
+  optional uint32 tid = 2;
+  optional uint64 from_instruction_start_address = 3;
+  optional uint64 to_instruction_start_address = 4;
+  optional uint64 instruction_size_bytes = 5;
+  oneof to_instructions {
+    bytes to_machine_code = 6;
+    bytes to_bytecode = 7;
+  }
+}
+
+message V8CodeDefaults {
+  optional uint32 tid = 1;
+}
+// End of protos/perfetto/trace/chrome/v8.proto
+
 // Begin of protos/perfetto/trace/clock_snapshot.proto
 
 // A snapshot of clock readings to allow for trace alignment.
@@ -11812,7 +12088,7 @@
 // emitted proactively in advance of referring to them in later packets.
 //
 // Next reserved id: 8 (up to 15).
-// Next id: 31.
+// Next id: 36.
 message InternedData {
   // TODO(eseckler): Replace iid fields inside interned messages with
   // map<iid, message> type fields in InternedData.
@@ -11874,6 +12150,21 @@
 
   // Interned packet context for android.network_packets.
   repeated NetworkPacketContext packet_context = 30;
+
+  // Interned name of a js function. We only intern js functions as there is a
+  // lot of duplication for them, but less so for other strings in the V8 data
+  // source.
+  repeated InternedV8String v8_js_function_name = 31;
+  // Js functions can be emitted multiple times for various compilation tiers,
+  // so it makes sense to deduplicate all this.
+  repeated InternedV8JsFunction v8_js_function = 32;
+  // Interned JS script (there is one associated with each JS function)
+  repeated InternedV8JsScript v8_js_script = 33;
+  // Interned Wasm script (there is one associated with each Wasm function)
+  repeated InternedV8WasmScript v8_wasm_script = 34;
+  // Every V8 event is associated with an isolate, intern the isolate to remove
+  // duplication.
+  repeated InternedV8Isolate v8_isolate = 35;
 }
 
 // End of protos/perfetto/trace/interned_data/interned_data.proto
@@ -13225,6 +13516,10 @@
 
   // Defaults for perf profiler packets (PerfSample).
   optional PerfSampleDefaults perf_sample_defaults = 12;
+
+  // Defaults for V8 code packets (V8JsCode, V8InternalCode, V8WasmCode,
+  // V8RegexpCode)
+  optional V8CodeDefaults v8_code_defaults = 99;
 }
 // End of protos/perfetto/trace/trace_packet_defaults.proto
 
@@ -13776,7 +14071,7 @@
 // See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
 //
 // Next reserved id: 14 (up to 15).
-// Next id: 99.
+// Next id: 104.
 message TracePacket {
   // The timestamp of the TracePacket.
   // By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -13901,6 +14196,12 @@
     // Events from the Windows etw infrastructure.
     EtwTraceEventBundle etw_events = 95;
 
+    V8JsCode v8_js_code = 99;
+    V8InternalCode v8_internal_code = 100;
+    V8WasmCode v8_wasm_code = 101;
+    V8RegExpCode v8_reg_exp_code = 102;
+    V8CodeMove v8_code_move = 103;
+
     // This field is only used for testing.
     // In previous versions of this proto this field had the id 268435455
     // This caused many problems:
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index e8306b7..0d1d976 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -35,6 +35,7 @@
 import "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto";
 import "protos/perfetto/trace/chrome/chrome_metadata.proto";
 import "protos/perfetto/trace/chrome/chrome_trace_event.proto";
+import "protos/perfetto/trace/chrome/v8.proto";
 import "protos/perfetto/trace/clock_snapshot.proto";
 import "protos/perfetto/trace/etw/etw_event_bundle.proto";
 import "protos/perfetto/trace/filesystem/inode_file_map.proto";
@@ -98,7 +99,7 @@
 // See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
 //
 // Next reserved id: 14 (up to 15).
-// Next id: 99.
+// Next id: 104.
 message TracePacket {
   // The timestamp of the TracePacket.
   // By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -223,6 +224,12 @@
     // Events from the Windows etw infrastructure.
     EtwTraceEventBundle etw_events = 95;
 
+    V8JsCode v8_js_code = 99;
+    V8InternalCode v8_internal_code = 100;
+    V8WasmCode v8_wasm_code = 101;
+    V8RegExpCode v8_reg_exp_code = 102;
+    V8CodeMove v8_code_move = 103;
+
     // This field is only used for testing.
     // In previous versions of this proto this field had the id 268435455
     // This caused many problems:
diff --git a/protos/perfetto/trace/trace_packet_defaults.proto b/protos/perfetto/trace/trace_packet_defaults.proto
index 0a25c0f..1114a1e 100644
--- a/protos/perfetto/trace/trace_packet_defaults.proto
+++ b/protos/perfetto/trace/trace_packet_defaults.proto
@@ -16,6 +16,7 @@
 
 syntax = "proto2";
 
+import "protos/perfetto/trace/chrome/v8.proto";
 import "protos/perfetto/trace/profiling/profile_packet.proto";
 import "protos/perfetto/trace/track_event/track_event.proto";
 
@@ -36,4 +37,8 @@
 
   // Defaults for perf profiler packets (PerfSample).
   optional PerfSampleDefaults perf_sample_defaults = 12;
+
+  // Defaults for V8 code packets (V8JsCode, V8InternalCode, V8WasmCode,
+  // V8RegexpCode)
+  optional V8CodeDefaults v8_code_defaults = 99;
 }
\ No newline at end of file