Chromium Code Reviews| 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..02a61de3e32fd79a32edcf71b6b60a5705a606e1 100644 |
| --- a/src/libplatform/tracing/trace-object.cc |
| +++ b/src/libplatform/tracing/trace-object.cc |
| @@ -6,11 +6,27 @@ |
| #include "src/base/platform/platform.h" |
| #include "src/base/platform/time.h" |
| +#include "src/tracing/trace-event.h" |
|
lpy
2016/07/28 21:18:20
I understand you need to use variables in the head
|
| namespace v8 { |
| namespace platform { |
| namespace tracing { |
| +// We perform checks for NULL strings since it is possible that a string arg |
| +// value is NULL. |
| +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. |
| +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 +40,67 @@ 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; |
| + int i = 0; |
| + for (; i < num_args; ++i) { |
| + arg_names_[i] = arg_names[i]; |
| + arg_values_[i].as_uint = arg_values[i]; |
| + arg_types_[i] = arg_types[i]; |
| + } |
| + // The NULL pointers tell us that these arguments are not used. |
| + for (; i < kTraceMaxNumArgs; ++i) { |
| + arg_names_[i] = NULL; |
| + } |
| + |
| + 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 (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 (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 (i = 0; i < num_args; ++i) { |
| + CopyTraceObjectParameter(&ptr, &arg_names_[i], end); |
| + } |
| + } |
| + for (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_; |
| @@ -51,12 +120,15 @@ void TraceObject::InitializeForTesting( |
| scope_ = scope; |
| id_ = id; |
| bind_id_ = bind_id; |
| - num_args_ = num_args; |
| flags_ = flags; |
| ts_ = ts; |
| tts_ = tts; |
| duration_ = duration; |
| cpu_duration_ = cpu_duration; |
| + |
| + for (int i = 0; i < kTraceMaxNumArgs; ++i) { |
| + arg_names_[i] = NULL; |
| + } |
| } |
| } // namespace tracing |