Use atomic sequence for sample trace ids

I noticed the current approach yielded collisions in the generated
sample trace ids on events with close timestamps, likely due to a
loss of precision in the way the hash seeds are casted and combined

In any case, for the sake of simplicity and performance (given the cost
of obtaining a timestamp with base::TimeTicks::now()) this implements
a helper that computes a trace id based on an atomic sequential number.

Bug: 390155857
Change-Id: I87969a7be30f30001655c63c8d93b49ad8158a00
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6227576
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Andres Olivares <andoli@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#98566}
diff --git a/BUILD.bazel b/BUILD.bazel
index 631cb5c0..5065af7 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -2489,6 +2489,7 @@
         "src/tracing/trace-event.cc",
         "src/tracing/trace-event.h",
         "src/tracing/trace-event-no-perfetto.h",
+        "src/tracing/trace-id.h",
         "src/tracing/traced-value.cc",
         "src/tracing/traced-value.h",
         "src/tracing/tracing-category-observer.cc",
diff --git a/BUILD.gn b/BUILD.gn
index 7ad7e11..ef1d419 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -4212,6 +4212,7 @@
     "src/torque/runtime-macro-shims.h",
     "src/tracing/trace-event-no-perfetto.h",
     "src/tracing/trace-event.h",
+    "src/tracing/trace-id.h",
     "src/tracing/traced-value.h",
     "src/tracing/tracing-category-observer.h",
     "src/utils/address-map.h",
diff --git a/src/inspector/v8-console.cc b/src/inspector/v8-console.cc
index fcc6ed9..ba504ff 100644
--- a/src/inspector/v8-console.cc
+++ b/src/inspector/v8-console.cc
@@ -26,6 +26,7 @@
 #include "src/inspector/v8-stack-trace-impl.h"
 #include "src/inspector/v8-value-utils.h"
 #include "src/tracing/trace-event.h"
+#include "src/tracing/trace-id.h"
 
 namespace v8_inspector {
 
@@ -461,16 +462,10 @@
   TRACE_EVENT(TRACE_DISABLED_BY_DEFAULT("v8.inspector"), "V8Console::TimeStamp",
               "data", ([&](perfetto::TracedValue context) {
                 auto dict = std::move(context).WriteDictionary();
-
-                uint64_t name_hash =
-                    std::hash<std::string>{}("V8Console::TimeStamp");
-                uint64_t timestamp_hash = std::hash<uint64_t>{}(
-                    v8::base::TimeTicks::Now().ToInternalValue());
-                uint64_t hash =
-                    v8::base::hash_combine(name_hash, timestamp_hash);
+                uint64_t trace_id = v8::tracing::TraceId();
                 v8::CpuProfiler::CpuProfiler::CollectSample(
-                    m_inspector->isolate(), hash);
-                dict.Add("sampleTraceId", hash);
+                    m_inspector->isolate(), trace_id);
+                dict.Add("sampleTraceId", trace_id);
                 static const char* kNames[] = {"name",  "start",      "end",
                                                "track", "trackGroup", "color"};
                 for (int i = 0; i < info.Length() &&
@@ -570,19 +565,14 @@
   m_inspector->asyncTaskStarted(taskInfo->Id());
   {
 #ifdef V8_USE_PERFETTO
-    TRACE_EVENT(
-        TRACE_DISABLED_BY_DEFAULT("v8.inspector"), "V8Console::runTask", "data",
-        ([&](perfetto::TracedValue context) {
-          auto dict = std::move(context).WriteDictionary();
-          uint64_t task_id_hash =
-              std::hash<uint64_t>{}(reinterpret_cast<uint64_t>(taskInfo->Id()));
-          uint64_t timestamp_hash = std::hash<uint64_t>{}(
-              v8::base::TimeTicks::Now().ToInternalValue());
-          uint64_t hash = v8::base::hash_combine(task_id_hash, timestamp_hash);
-
-          v8::CpuProfiler::CpuProfiler::CollectSample(isolate, hash);
-          dict.Add("sampleTraceId", hash);
-        }));
+    TRACE_EVENT(TRACE_DISABLED_BY_DEFAULT("v8.inspector"), "V8Console::runTask",
+                "data", ([&](perfetto::TracedValue context) {
+                  uint64_t trace_id = v8::tracing::TraceId();
+                  auto dict = std::move(context).WriteDictionary();
+                  v8::CpuProfiler::CpuProfiler::CollectSample(isolate,
+                                                              trace_id);
+                  dict.Add("sampleTraceId", trace_id);
+                }));
 #endif  // V8_USE_PERFETTO
 
     v8::Local<v8::Value> result;
diff --git a/src/tracing/trace-id.h b/src/tracing/trace-id.h
new file mode 100644
index 0000000..f594340
--- /dev/null
+++ b/src/tracing/trace-id.h
@@ -0,0 +1,19 @@
+// Copyright 2025 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.
+
+#ifndef V8_TRACING_TRACE_ID_H_
+#define V8_TRACING_TRACE_ID_H_
+
+#include "src/base/platform/platform.h"
+
+namespace v8 {
+namespace tracing {
+V8_INLINE uint64_t TraceId() {
+  static std::atomic<uint64_t> sequence_number(0);
+  return sequence_number.fetch_add(1, std::memory_order_relaxed);
+}
+}  // namespace tracing
+}  // namespace v8
+
+#endif  // V8_TRACING_TRACE_ID_H_