Index: src/libplatform/tracing/trace-object.cc |
diff --git a/src/libplatform/tracing/trace-object.cc b/src/libplatform/tracing/trace-object.cc |
index f8a827409d28872ed93df8a430b2dc86cc54698a..f8ad9f9f7d49a5ea0851513dad0d2453ccc6fba0 100644 |
--- a/src/libplatform/tracing/trace-object.cc |
+++ b/src/libplatform/tracing/trace-object.cc |
@@ -4,6 +4,7 @@ |
#include "include/libplatform/v8-tracing.h" |
+#include "base/trace_event/common/trace_event_common.h" |
Nico
2016/08/03 19:34:51
This is no good, things not in chromium's repo mus
|
#include "src/base/platform/platform.h" |
#include "src/base/platform/time.h" |
@@ -11,6 +12,24 @@ namespace v8 { |
namespace platform { |
namespace tracing { |
+// We perform checks for NULL strings since it is possible that a string arg |
+// value is NULL. |
+V8_INLINE static size_t GetAllocLength(const char* str) { |
+ return str ? strlen(str) + 1 : 0; |
+} |
+ |
+// Copies |*member| into |*buffer|, sets |*member| to point to this new |
+// location, and then advances |*buffer| by the amount written. |
+V8_INLINE static void CopyTraceObjectParameter(char** buffer, |
+ const char** member, |
+ const char* end) { |
+ if (*member) { |
+ strncpy(*buffer, *member, end - *buffer); |
+ *member = *buffer; |
+ *buffer += strlen(*member) + 1; |
+ } |
+} |
+ |
void TraceObject::Initialize(char phase, const uint8_t* category_enabled_flag, |
const char* name, const char* scope, uint64_t id, |
uint64_t bind_id, int num_args, |
@@ -24,14 +43,62 @@ void TraceObject::Initialize(char phase, const uint8_t* category_enabled_flag, |
scope_ = scope; |
id_ = id; |
bind_id_ = bind_id; |
- num_args_ = num_args; |
flags_ = flags; |
ts_ = base::TimeTicks::HighResolutionNow().ToInternalValue(); |
tts_ = base::ThreadTicks::Now().ToInternalValue(); |
duration_ = 0; |
cpu_duration_ = 0; |
+ |
+ // Clamp num_args since it may have been set by a third-party library. |
+ num_args_ = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args; |
+ for (int i = 0; i < num_args_; ++i) { |
+ arg_names_[i] = arg_names[i]; |
+ arg_values_[i].as_uint = arg_values[i]; |
+ arg_types_[i] = arg_types[i]; |
+ } |
+ |
+ bool copy = !!(flags & TRACE_EVENT_FLAG_COPY); |
+ // Allocate a long string to fit all string copies. |
+ size_t alloc_size = 0; |
+ if (copy) { |
+ alloc_size += GetAllocLength(name) + GetAllocLength(scope); |
+ for (int i = 0; i < num_args_; ++i) { |
+ alloc_size += GetAllocLength(arg_names_[i]); |
+ if (arg_types_[i] == TRACE_VALUE_TYPE_STRING) |
+ arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING; |
+ } |
+ } |
+ |
+ bool arg_is_copy[kTraceMaxNumArgs]; |
+ for (int i = 0; i < num_args_; ++i) { |
+ // We only take a copy of arg_vals if they are of type COPY_STRING. |
+ arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING); |
+ if (arg_is_copy[i]) alloc_size += GetAllocLength(arg_values_[i].as_string); |
+ } |
+ |
+ if (alloc_size) { |
+ // Since TraceObject can be initialized multiple times, we might need |
+ // to free old memory. |
+ delete[] parameter_copy_storage_; |
+ char* ptr = parameter_copy_storage_ = new char[alloc_size]; |
+ const char* end = ptr + alloc_size; |
+ if (copy) { |
+ CopyTraceObjectParameter(&ptr, &name_, end); |
+ CopyTraceObjectParameter(&ptr, &scope_, end); |
+ for (int i = 0; i < num_args_; ++i) { |
+ CopyTraceObjectParameter(&ptr, &arg_names_[i], end); |
+ } |
+ } |
+ for (int i = 0; i < num_args_; ++i) { |
+ if (arg_is_copy[i]) { |
+ CopyTraceObjectParameter(&ptr, &arg_values_[i].as_string, end); |
+ } |
+ } |
+ } |
} |
+TraceObject::~TraceObject() { delete[] parameter_copy_storage_; } |
+ |
void TraceObject::UpdateDuration() { |
duration_ = base::TimeTicks::HighResolutionNow().ToInternalValue() - ts_; |
cpu_duration_ = base::ThreadTicks::Now().ToInternalValue() - tts_; |