diff --git a/common.gypi b/common.gypi index 2f1efe4f56c787..c480c52849ce6f 100644 --- a/common.gypi +++ b/common.gypi @@ -27,7 +27,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.1', + 'v8_embedder_string': '-node.3', # Enable disassembler for `--print-code` v8 options 'v8_enable_disassembler': 1, diff --git a/deps/v8/include/libplatform/v8-tracing.h b/deps/v8/include/libplatform/v8-tracing.h index 8c1febf7627ae7..9dcf3d7bca760a 100644 --- a/deps/v8/include/libplatform/v8-tracing.h +++ b/deps/v8/include/libplatform/v8-tracing.h @@ -43,8 +43,8 @@ class V8_PLATFORM_EXPORT TraceObject { const char** arg_names, const uint8_t* arg_types, const uint64_t* arg_values, std::unique_ptr* arg_convertables, - unsigned int flags); - void UpdateDuration(); + unsigned int flags, int64_t timestamp, int64_t cpu_timestamp); + void UpdateDuration(int64_t timestamp, int64_t cpu_timestamp); void InitializeForTesting( char phase, const uint8_t* category_enabled_flag, const char* name, const char* scope, uint64_t id, uint64_t bind_id, int num_args, @@ -247,6 +247,13 @@ class V8_PLATFORM_EXPORT TracingController const uint64_t* arg_values, std::unique_ptr* arg_convertables, unsigned int flags) override; + uint64_t AddTraceEventWithTimestamp( + char phase, const uint8_t* category_enabled_flag, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, + std::unique_ptr* arg_convertables, + unsigned int flags, int64_t timestamp) override; void UpdateTraceEventDuration(const uint8_t* category_enabled_flag, const char* name, uint64_t handle) override; void AddTraceStateObserver( @@ -259,6 +266,10 @@ class V8_PLATFORM_EXPORT TracingController static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag); + protected: + virtual int64_t CurrentTimestampMicroseconds(); + virtual int64_t CurrentCpuTimestampMicroseconds(); + private: const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group); void UpdateCategoryGroupEnabledFlag(size_t category_index); diff --git a/deps/v8/include/v8-platform.h b/deps/v8/include/v8-platform.h index f814543e6667c9..43420a972c7b1a 100644 --- a/deps/v8/include/v8-platform.h +++ b/deps/v8/include/v8-platform.h @@ -119,11 +119,11 @@ class TracingController { } /** - * Adds a trace event to the platform tracing system. This function call is + * Adds a trace event to the platform tracing system. These function calls are * usually the result of a TRACE_* macro from trace_event_common.h when * tracing and the category of the particular trace are enabled. It is not - * advisable to call this function on its own; it is really only meant to be - * used by the trace macros. The returned handle can be used by + * advisable to call these functions on their own; they are really only meant + * to be used by the trace macros. The returned handle can be used by * UpdateTraceEventDuration to update the duration of COMPLETE events. */ virtual uint64_t AddTraceEvent( @@ -135,6 +135,15 @@ class TracingController { unsigned int flags) { return 0; } + virtual uint64_t AddTraceEventWithTimestamp( + char phase, const uint8_t* category_enabled_flag, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, + std::unique_ptr* arg_convertables, + unsigned int flags, int64_t timestamp) { + return 0; + } /** * Sets the duration field of a COMPLETE trace event. It must be called with diff --git a/deps/v8/src/libplatform/tracing/trace-object.cc b/deps/v8/src/libplatform/tracing/trace-object.cc index 6d1a6d62b5d317..6b6e0cf404d3fd 100644 --- a/deps/v8/src/libplatform/tracing/trace-object.cc +++ b/deps/v8/src/libplatform/tracing/trace-object.cc @@ -37,7 +37,7 @@ void TraceObject::Initialize( const char** arg_names, const uint8_t* arg_types, const uint64_t* arg_values, std::unique_ptr* arg_convertables, - unsigned int flags) { + unsigned int flags, int64_t timestamp, int64_t cpu_timestamp) { pid_ = base::OS::GetCurrentProcessId(); tid_ = base::OS::GetCurrentThreadId(); phase_ = phase; @@ -47,8 +47,8 @@ void TraceObject::Initialize( id_ = id; bind_id_ = bind_id; flags_ = flags; - ts_ = base::TimeTicks::HighResolutionNow().ToInternalValue(); - tts_ = base::ThreadTicks::Now().ToInternalValue(); + ts_ = timestamp; + tts_ = cpu_timestamp; duration_ = 0; cpu_duration_ = 0; @@ -103,9 +103,9 @@ void TraceObject::Initialize( TraceObject::~TraceObject() { delete[] parameter_copy_storage_; } -void TraceObject::UpdateDuration() { - duration_ = base::TimeTicks::HighResolutionNow().ToInternalValue() - ts_; - cpu_duration_ = base::ThreadTicks::Now().ToInternalValue() - tts_; +void TraceObject::UpdateDuration(int64_t timestamp, int64_t cpu_timestamp) { + duration_ = timestamp - ts_; + cpu_duration_ = cpu_timestamp - tts_; } void TraceObject::InitializeForTesting( diff --git a/deps/v8/src/libplatform/tracing/tracing-controller.cc b/deps/v8/src/libplatform/tracing/tracing-controller.cc index 0c44e227349f38..647306d62790af 100644 --- a/deps/v8/src/libplatform/tracing/tracing-controller.cc +++ b/deps/v8/src/libplatform/tracing/tracing-controller.cc @@ -9,6 +9,7 @@ #include "src/base/atomicops.h" #include "src/base/platform/mutex.h" +#include "src/base/platform/time.h" namespace v8 { namespace platform { @@ -48,6 +49,14 @@ void TracingController::Initialize(TraceBuffer* trace_buffer) { mutex_.reset(new base::Mutex()); } +int64_t TracingController::CurrentTimestampMicroseconds() { + return base::TimeTicks::HighResolutionNow().ToInternalValue(); +} + +int64_t TracingController::CurrentCpuTimestampMicroseconds() { + return base::ThreadTicks::Now().ToInternalValue(); +} + uint64_t TracingController::AddTraceEvent( char phase, const uint8_t* category_enabled_flag, const char* name, const char* scope, uint64_t id, uint64_t bind_id, int num_args, @@ -57,10 +66,29 @@ uint64_t TracingController::AddTraceEvent( unsigned int flags) { uint64_t handle; TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle); + if (trace_object) { + trace_object->Initialize( + phase, category_enabled_flag, name, scope, id, bind_id, num_args, + arg_names, arg_types, arg_values, arg_convertables, flags, + CurrentTimestampMicroseconds(), CurrentCpuTimestampMicroseconds()); + } + return handle; +} + +uint64_t TracingController::AddTraceEventWithTimestamp( + char phase, const uint8_t* category_enabled_flag, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, + std::unique_ptr* arg_convertables, + unsigned int flags, int64_t timestamp) { + uint64_t handle; + TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle); if (trace_object) { trace_object->Initialize(phase, category_enabled_flag, name, scope, id, bind_id, num_args, arg_names, arg_types, - arg_values, arg_convertables, flags); + arg_values, arg_convertables, flags, timestamp, + CurrentCpuTimestampMicroseconds()); } return handle; } @@ -69,7 +97,8 @@ void TracingController::UpdateTraceEventDuration( const uint8_t* category_enabled_flag, const char* name, uint64_t handle) { TraceObject* trace_object = trace_buffer_->GetEventByHandle(handle); if (!trace_object) return; - trace_object->UpdateDuration(); + trace_object->UpdateDuration(CurrentTimestampMicroseconds(), + CurrentCpuTimestampMicroseconds()); } const uint8_t* TracingController::GetCategoryGroupEnabled( diff --git a/deps/v8/src/tracing/trace-event.h b/deps/v8/src/tracing/trace-event.h index d237aed7208f8f..bc73996be93495 100644 --- a/deps/v8/src/tracing/trace-event.h +++ b/deps/v8/src/tracing/trace-event.h @@ -96,6 +96,23 @@ enum CategoryGroupEnabledFlags { // unsigned int flags) #define TRACE_EVENT_API_ADD_TRACE_EVENT v8::internal::tracing::AddTraceEventImpl +// Add a trace event to the platform tracing system. +// uint64_t TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( +// char phase, +// const uint8_t* category_group_enabled, +// const char* name, +// const char* scope, +// uint64_t id, +// uint64_t bind_id, +// int num_args, +// const char** arg_names, +// const uint8_t* arg_types, +// const uint64_t* arg_values, +// unsigned int flags, +// int64_t timestamp) +#define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP \ + v8::internal::tracing::AddTraceEventWithTimestampImpl + // Set the duration field of a COMPLETE trace event. // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( // const uint8_t* category_group_enabled, @@ -212,10 +229,18 @@ enum CategoryGroupEnabledFlags { } \ } while (0) -// Adds a trace event with a given timestamp. Not Implemented. +// Adds a trace event with a given timestamp. #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \ timestamp, flags, ...) \ - UNIMPLEMENTED() + do { \ + INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ + if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ + v8::internal::tracing::AddTraceEventWithTimestamp( \ + phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ + v8::internal::tracing::kGlobalScope, v8::internal::tracing::kNoId, \ + v8::internal::tracing::kNoId, flags, timestamp, ##__VA_ARGS__); \ + } \ + } while (0) // Adds a trace event with a given id and timestamp. Not Implemented. #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_AND_TIMESTAMP( \ @@ -431,6 +456,28 @@ static V8_INLINE uint64_t AddTraceEventImpl( arg_values, arg_convertables, flags); } +static V8_INLINE uint64_t AddTraceEventWithTimestampImpl( + char phase, const uint8_t* category_group_enabled, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, unsigned int flags, int64_t timestamp) { + std::unique_ptr arg_convertables[2]; + if (num_args > 0 && arg_types[0] == TRACE_VALUE_TYPE_CONVERTABLE) { + arg_convertables[0].reset(reinterpret_cast( + static_cast(arg_values[0]))); + } + if (num_args > 1 && arg_types[1] == TRACE_VALUE_TYPE_CONVERTABLE) { + arg_convertables[1].reset(reinterpret_cast( + static_cast(arg_values[1]))); + } + DCHECK_LE(num_args, 2); + v8::TracingController* controller = + v8::internal::tracing::TraceEventHelper::GetTracingController(); + return controller->AddTraceEventWithTimestamp( + phase, category_group_enabled, name, scope, id, bind_id, num_args, + arg_names, arg_types, arg_values, arg_convertables, flags, timestamp); +} + // Define SetTraceValue for each allowed type. It stores the type and // value in the return arguments. This allows this API to avoid declaring any // structures so that it is portable to third_party libraries. @@ -533,6 +580,48 @@ static V8_INLINE uint64_t AddTraceEvent( arg_names, arg_types, arg_values, flags); } +static V8_INLINE uint64_t AddTraceEventWithTimestamp( + char phase, const uint8_t* category_group_enabled, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags, + int64_t timestamp) { + return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( + phase, category_group_enabled, name, scope, id, bind_id, kZeroNumArgs, + nullptr, nullptr, nullptr, flags, timestamp); +} + +template +static V8_INLINE uint64_t AddTraceEventWithTimestamp( + char phase, const uint8_t* category_group_enabled, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags, + int64_t timestamp, const char* arg1_name, ARG1_TYPE&& arg1_val) { + const int num_args = 1; + uint8_t arg_type; + uint64_t arg_value; + SetTraceValue(std::forward(arg1_val), &arg_type, &arg_value); + return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( + phase, category_group_enabled, name, scope, id, bind_id, num_args, + &arg1_name, &arg_type, &arg_value, flags, timestamp); +} + +template +static V8_INLINE uint64_t AddTraceEventWithTimestamp( + char phase, const uint8_t* category_group_enabled, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, unsigned int flags, + int64_t timestamp, const char* arg1_name, ARG1_TYPE&& arg1_val, + const char* arg2_name, ARG2_TYPE&& arg2_val) { + const int num_args = 2; + const char* arg_names[2] = {arg1_name, arg2_name}; + unsigned char arg_types[2]; + uint64_t arg_values[2]; + SetTraceValue(std::forward(arg1_val), &arg_types[0], + &arg_values[0]); + SetTraceValue(std::forward(arg2_val), &arg_types[1], + &arg_values[1]); + return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( + phase, category_group_enabled, name, scope, id, bind_id, num_args, + arg_names, arg_types, arg_values, flags, timestamp); +} + // Used by TRACE_EVENTx macros. Do not use directly. class ScopedTracer { public: diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassFields.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassFields.golden index e3a828e1cc527c..afb3d3e8de5815 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassFields.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassFields.golden @@ -15,7 +15,7 @@ snippet: " static c; static ['d']; } - + class B { a = 1; ['b'] = this.a; @@ -138,7 +138,7 @@ snippet: " static c; static ['d']; } - + class B extends class {} { a = 1; ['b'] = this.a; @@ -149,7 +149,7 @@ snippet: " super(); } } - + class C extends B { a = 1; ['b'] = this.a; @@ -159,7 +159,7 @@ snippet: " (() => super())(); } } - + new A; new B; new C; @@ -335,3 +335,4 @@ constant pool: [ ] handlers: [ ] + diff --git a/deps/v8/test/cctest/libplatform/test-tracing.cc b/deps/v8/test/cctest/libplatform/test-tracing.cc index dd3f30d621f445..da202057de312c 100644 --- a/deps/v8/test/cctest/libplatform/test-tracing.cc +++ b/deps/v8/test/cctest/libplatform/test-tracing.cc @@ -42,7 +42,7 @@ TEST(TestTraceObject) { uint8_t category_enabled_flag = 41; trace_object.Initialize('X', &category_enabled_flag, "Test.Trace", "Test.Scope", 42, 123, 0, nullptr, nullptr, nullptr, - nullptr, 0); + nullptr, 0, 1729, 4104); CHECK_EQ('X', trace_object.phase()); CHECK_EQ(category_enabled_flag, *trace_object.category_enabled_flag()); CHECK_EQ(std::string("Test.Trace"), std::string(trace_object.name())); @@ -96,7 +96,7 @@ TEST(TestTraceBufferRingBuffer) { CHECK_NOT_NULL(trace_object); trace_object->Initialize('X', &category_enabled_flag, names[i].c_str(), "Test.Scope", 42, 123, 0, nullptr, nullptr, - nullptr, nullptr, 0); + nullptr, nullptr, 0, 1729, 4104); trace_object = ring_buffer->GetEventByHandle(handles[i]); CHECK_NOT_NULL(trace_object); CHECK_EQ('X', trace_object->phase()); diff --git a/deps/v8/test/cctest/test-trace-event.cc b/deps/v8/test/cctest/test-trace-event.cc index 9705afb4efca0d..471619062a02d3 100644 --- a/deps/v8/test/cctest/test-trace-event.cc +++ b/deps/v8/test/cctest/test-trace-event.cc @@ -22,14 +22,16 @@ struct MockTraceObject { uint64_t bind_id; int num_args; unsigned int flags; + int64_t timestamp; MockTraceObject(char phase, std::string name, uint64_t id, uint64_t bind_id, - int num_args, int flags) + int num_args, int flags, int64_t timestamp) : phase(phase), name(name), id(id), bind_id(bind_id), num_args(num_args), - flags(flags) {} + flags(flags), + timestamp(timestamp) {} }; typedef std::vector MockTraceObjectList; @@ -51,8 +53,20 @@ class MockTracingController : public v8::TracingController { const uint64_t* arg_values, std::unique_ptr* arg_convertables, unsigned int flags) override { - MockTraceObject* to = new MockTraceObject(phase, std::string(name), id, - bind_id, num_args, flags); + return AddTraceEventWithTimestamp( + phase, category_enabled_flag, name, scope, id, bind_id, num_args, + arg_names, arg_types, arg_values, arg_convertables, flags, 0); + } + + uint64_t AddTraceEventWithTimestamp( + char phase, const uint8_t* category_enabled_flag, const char* name, + const char* scope, uint64_t id, uint64_t bind_id, int num_args, + const char** arg_names, const uint8_t* arg_types, + const uint64_t* arg_values, + std::unique_ptr* arg_convertables, + unsigned int flags, int64_t timestamp) override { + MockTraceObject* to = new MockTraceObject( + phase, std::string(name), id, bind_id, num_args, flags, timestamp); trace_object_list_.push_back(to); return 0; } @@ -239,3 +253,24 @@ TEST(TestEventInContext) { CHECK_EQ("Isolate", GET_TRACE_OBJECT(2)->name); CHECK_EQ(isolate_id, GET_TRACE_OBJECT(2)->id); } + +TEST(TestEventWithTimestamp) { + MockTracingPlatform platform; + + TRACE_EVENT_INSTANT_WITH_TIMESTAMP0("v8-cat", "0arg", + TRACE_EVENT_SCOPE_GLOBAL, 1729); + TRACE_EVENT_INSTANT_WITH_TIMESTAMP1("v8-cat", "1arg", + TRACE_EVENT_SCOPE_GLOBAL, 4104, "val", 1); + TRACE_EVENT_MARK_WITH_TIMESTAMP2("v8-cat", "mark", 13832, "a", 1, "b", 2); + + CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->size()); + + CHECK_EQ(1729, GET_TRACE_OBJECT(0)->timestamp); + CHECK_EQ(0, GET_TRACE_OBJECT(0)->num_args); + + CHECK_EQ(4104, GET_TRACE_OBJECT(1)->timestamp); + CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args); + + CHECK_EQ(13832, GET_TRACE_OBJECT(2)->timestamp); + CHECK_EQ(2, GET_TRACE_OBJECT(2)->num_args); +}