Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 1 | // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | #include <stdlib.h> |
| 5 | #include <string.h> |
| 6 | |
| 7 | #include "src/v8.h" |
| 8 | |
| 9 | #include "src/list.h" |
| 10 | #include "src/list-inl.h" |
| 11 | #include "test/cctest/cctest.h" |
| 12 | |
| 13 | using v8::IdleTask; |
| 14 | using v8::Task; |
| 15 | using v8::Isolate; |
| 16 | |
| 17 | #include "src/tracing/trace-event.h" |
| 18 | |
| 19 | #define GET_TRACE_OBJECTS_LIST platform.GetMockTraceObjects() |
| 20 | |
| 21 | #define GET_TRACE_OBJECT(Index) GET_TRACE_OBJECTS_LIST->at(Index) |
| 22 | |
| 23 | |
| 24 | struct MockTraceObject { |
| 25 | char phase; |
| 26 | std::string name; |
| 27 | uint64_t id; |
| 28 | uint64_t bind_id; |
| 29 | int num_args; |
| 30 | unsigned int flags; |
| 31 | MockTraceObject(char phase, std::string name, uint64_t id, uint64_t bind_id, |
| 32 | int num_args, int flags) |
| 33 | : phase(phase), |
| 34 | name(name), |
| 35 | id(id), |
| 36 | bind_id(bind_id), |
| 37 | num_args(num_args), |
| 38 | flags(flags) {} |
| 39 | }; |
| 40 | |
| 41 | typedef v8::internal::List<MockTraceObject*> MockTraceObjectList; |
| 42 | |
| 43 | class MockTracingPlatform : public v8::Platform { |
| 44 | public: |
| 45 | explicit MockTracingPlatform(v8::Platform* platform) {} |
| 46 | virtual ~MockTracingPlatform() { |
| 47 | for (int i = 0; i < trace_object_list_.length(); ++i) { |
| 48 | delete trace_object_list_[i]; |
| 49 | } |
| 50 | trace_object_list_.Clear(); |
| 51 | } |
| 52 | void CallOnBackgroundThread(Task* task, |
| 53 | ExpectedRuntime expected_runtime) override {} |
| 54 | |
| 55 | void CallOnForegroundThread(Isolate* isolate, Task* task) override {} |
| 56 | |
| 57 | void CallDelayedOnForegroundThread(Isolate* isolate, Task* task, |
| 58 | double delay_in_seconds) override {} |
| 59 | |
| 60 | double MonotonicallyIncreasingTime() override { return 0.0; } |
| 61 | |
| 62 | void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) override {} |
| 63 | |
| 64 | bool IdleTasksEnabled(Isolate* isolate) override { return false; } |
| 65 | |
| 66 | bool PendingIdleTask() { return false; } |
| 67 | |
| 68 | void PerformIdleTask(double idle_time_in_seconds) {} |
| 69 | |
| 70 | bool PendingDelayedTask() { return false; } |
| 71 | |
| 72 | void PerformDelayedTask() {} |
| 73 | |
| 74 | uint64_t AddTraceEvent(char phase, const uint8_t* category_enabled_flag, |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame^] | 75 | const char* name, const char* scope, uint64_t id, |
| 76 | uint64_t bind_id, int num_args, const char** arg_names, |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 77 | const uint8_t* arg_types, const uint64_t* arg_values, |
| 78 | unsigned int flags) override { |
| 79 | MockTraceObject* to = new MockTraceObject(phase, std::string(name), id, |
| 80 | bind_id, num_args, flags); |
| 81 | trace_object_list_.Add(to); |
| 82 | return 0; |
| 83 | } |
| 84 | |
| 85 | void UpdateTraceEventDuration(const uint8_t* category_enabled_flag, |
| 86 | const char* name, uint64_t handle) override {} |
| 87 | |
| 88 | const uint8_t* GetCategoryGroupEnabled(const char* name) override { |
| 89 | if (strcmp(name, "v8-cat")) { |
| 90 | static uint8_t no = 0; |
| 91 | return &no; |
| 92 | } else { |
| 93 | static uint8_t yes = 0x7; |
| 94 | return &yes; |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | const char* GetCategoryGroupName( |
| 99 | const uint8_t* category_enabled_flag) override { |
| 100 | static const char dummy[] = "dummy"; |
| 101 | return dummy; |
| 102 | } |
| 103 | |
| 104 | MockTraceObjectList* GetMockTraceObjects() { return &trace_object_list_; } |
| 105 | |
| 106 | private: |
| 107 | MockTraceObjectList trace_object_list_; |
| 108 | }; |
| 109 | |
| 110 | |
| 111 | TEST(TraceEventDisabledCategory) { |
| 112 | v8::Platform* old_platform = i::V8::GetCurrentPlatform(); |
| 113 | MockTracingPlatform platform(old_platform); |
| 114 | i::V8::SetPlatformForTesting(&platform); |
| 115 | |
| 116 | // Disabled category, will not add events. |
| 117 | TRACE_EVENT_BEGIN0("cat", "e1"); |
| 118 | TRACE_EVENT_END0("cat", "e1"); |
| 119 | CHECK_EQ(0, GET_TRACE_OBJECTS_LIST->length()); |
| 120 | |
| 121 | i::V8::SetPlatformForTesting(old_platform); |
| 122 | } |
| 123 | |
| 124 | |
| 125 | TEST(TraceEventNoArgs) { |
| 126 | v8::Platform* old_platform = i::V8::GetCurrentPlatform(); |
| 127 | MockTracingPlatform platform(old_platform); |
| 128 | i::V8::SetPlatformForTesting(&platform); |
| 129 | |
| 130 | // Enabled category will add 2 events. |
| 131 | TRACE_EVENT_BEGIN0("v8-cat", "e1"); |
| 132 | TRACE_EVENT_END0("v8-cat", "e1"); |
| 133 | |
| 134 | CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->length()); |
| 135 | CHECK_EQ('B', GET_TRACE_OBJECT(0)->phase); |
| 136 | CHECK_EQ("e1", GET_TRACE_OBJECT(0)->name); |
| 137 | CHECK_EQ(0, GET_TRACE_OBJECT(0)->num_args); |
| 138 | |
| 139 | CHECK_EQ('E', GET_TRACE_OBJECT(1)->phase); |
| 140 | CHECK_EQ("e1", GET_TRACE_OBJECT(1)->name); |
| 141 | CHECK_EQ(0, GET_TRACE_OBJECT(1)->num_args); |
| 142 | |
| 143 | i::V8::SetPlatformForTesting(old_platform); |
| 144 | } |
| 145 | |
| 146 | |
| 147 | TEST(TraceEventWithOneArg) { |
| 148 | v8::Platform* old_platform = i::V8::GetCurrentPlatform(); |
| 149 | MockTracingPlatform platform(old_platform); |
| 150 | i::V8::SetPlatformForTesting(&platform); |
| 151 | |
| 152 | TRACE_EVENT_BEGIN1("v8-cat", "e1", "arg1", 42); |
| 153 | TRACE_EVENT_END1("v8-cat", "e1", "arg1", 42); |
| 154 | TRACE_EVENT_BEGIN1("v8-cat", "e2", "arg1", "abc"); |
| 155 | TRACE_EVENT_END1("v8-cat", "e2", "arg1", "abc"); |
| 156 | |
| 157 | CHECK_EQ(4, GET_TRACE_OBJECTS_LIST->length()); |
| 158 | |
| 159 | CHECK_EQ(1, GET_TRACE_OBJECT(0)->num_args); |
| 160 | CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args); |
| 161 | CHECK_EQ(1, GET_TRACE_OBJECT(2)->num_args); |
| 162 | CHECK_EQ(1, GET_TRACE_OBJECT(3)->num_args); |
| 163 | |
| 164 | i::V8::SetPlatformForTesting(old_platform); |
| 165 | } |
| 166 | |
| 167 | |
| 168 | TEST(TraceEventWithTwoArgs) { |
| 169 | v8::Platform* old_platform = i::V8::GetCurrentPlatform(); |
| 170 | MockTracingPlatform platform(old_platform); |
| 171 | i::V8::SetPlatformForTesting(&platform); |
| 172 | |
| 173 | TRACE_EVENT_BEGIN2("v8-cat", "e1", "arg1", 42, "arg2", "abc"); |
| 174 | TRACE_EVENT_END2("v8-cat", "e1", "arg1", 42, "arg2", "abc"); |
| 175 | TRACE_EVENT_BEGIN2("v8-cat", "e2", "arg1", "abc", "arg2", 43); |
| 176 | TRACE_EVENT_END2("v8-cat", "e2", "arg1", "abc", "arg2", 43); |
| 177 | |
| 178 | CHECK_EQ(4, GET_TRACE_OBJECTS_LIST->length()); |
| 179 | |
| 180 | CHECK_EQ(2, GET_TRACE_OBJECT(0)->num_args); |
| 181 | CHECK_EQ(2, GET_TRACE_OBJECT(1)->num_args); |
| 182 | CHECK_EQ(2, GET_TRACE_OBJECT(2)->num_args); |
| 183 | CHECK_EQ(2, GET_TRACE_OBJECT(3)->num_args); |
| 184 | |
| 185 | i::V8::SetPlatformForTesting(old_platform); |
| 186 | } |
| 187 | |
| 188 | |
| 189 | TEST(ScopedTraceEvent) { |
| 190 | v8::Platform* old_platform = i::V8::GetCurrentPlatform(); |
| 191 | MockTracingPlatform platform(old_platform); |
| 192 | i::V8::SetPlatformForTesting(&platform); |
| 193 | |
| 194 | { TRACE_EVENT0("v8-cat", "e"); } |
| 195 | |
| 196 | CHECK_EQ(1, GET_TRACE_OBJECTS_LIST->length()); |
| 197 | CHECK_EQ(0, GET_TRACE_OBJECT(0)->num_args); |
| 198 | |
| 199 | { TRACE_EVENT1("v8-cat", "e1", "arg1", "abc"); } |
| 200 | |
| 201 | CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->length()); |
| 202 | CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args); |
| 203 | |
| 204 | { TRACE_EVENT2("v8-cat", "e1", "arg1", "abc", "arg2", 42); } |
| 205 | |
| 206 | CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->length()); |
| 207 | CHECK_EQ(2, GET_TRACE_OBJECT(2)->num_args); |
| 208 | |
| 209 | i::V8::SetPlatformForTesting(old_platform); |
| 210 | } |
| 211 | |
| 212 | |
| 213 | TEST(TestEventWithFlow) { |
| 214 | v8::Platform* old_platform = i::V8::GetCurrentPlatform(); |
| 215 | MockTracingPlatform platform(old_platform); |
| 216 | i::V8::SetPlatformForTesting(&platform); |
| 217 | |
| 218 | static uint64_t bind_id = 21; |
| 219 | { |
| 220 | TRACE_EVENT_WITH_FLOW0("v8-cat", "f1", bind_id, TRACE_EVENT_FLAG_FLOW_OUT); |
| 221 | } |
| 222 | { |
| 223 | TRACE_EVENT_WITH_FLOW0( |
| 224 | "v8-cat", "f2", bind_id, |
| 225 | TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); |
| 226 | } |
| 227 | { TRACE_EVENT_WITH_FLOW0("v8-cat", "f3", bind_id, TRACE_EVENT_FLAG_FLOW_IN); } |
| 228 | |
| 229 | CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->length()); |
| 230 | CHECK_EQ(bind_id, GET_TRACE_OBJECT(0)->bind_id); |
| 231 | CHECK_EQ(TRACE_EVENT_FLAG_FLOW_OUT, GET_TRACE_OBJECT(0)->flags); |
| 232 | CHECK_EQ(bind_id, GET_TRACE_OBJECT(1)->bind_id); |
| 233 | CHECK_EQ(TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, |
| 234 | GET_TRACE_OBJECT(1)->flags); |
| 235 | CHECK_EQ(bind_id, GET_TRACE_OBJECT(2)->bind_id); |
| 236 | CHECK_EQ(TRACE_EVENT_FLAG_FLOW_IN, GET_TRACE_OBJECT(2)->flags); |
| 237 | |
| 238 | i::V8::SetPlatformForTesting(old_platform); |
| 239 | } |
| 240 | |
| 241 | |
| 242 | TEST(TestEventWithId) { |
| 243 | v8::Platform* old_platform = i::V8::GetCurrentPlatform(); |
| 244 | MockTracingPlatform platform(old_platform); |
| 245 | i::V8::SetPlatformForTesting(&platform); |
| 246 | |
| 247 | static uint64_t event_id = 21; |
| 248 | TRACE_EVENT_ASYNC_BEGIN0("v8-cat", "a1", event_id); |
| 249 | TRACE_EVENT_ASYNC_END0("v8-cat", "a1", event_id); |
| 250 | |
| 251 | CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->length()); |
| 252 | CHECK_EQ(TRACE_EVENT_PHASE_ASYNC_BEGIN, GET_TRACE_OBJECT(0)->phase); |
| 253 | CHECK_EQ(event_id, GET_TRACE_OBJECT(0)->id); |
| 254 | CHECK_EQ(TRACE_EVENT_PHASE_ASYNC_END, GET_TRACE_OBJECT(1)->phase); |
| 255 | CHECK_EQ(event_id, GET_TRACE_OBJECT(1)->id); |
| 256 | |
| 257 | i::V8::SetPlatformForTesting(old_platform); |
| 258 | } |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame^] | 259 | |
| 260 | TEST(TestEventInContext) { |
| 261 | v8::Platform* old_platform = i::V8::GetCurrentPlatform(); |
| 262 | MockTracingPlatform platform(old_platform); |
| 263 | i::V8::SetPlatformForTesting(&platform); |
| 264 | |
| 265 | static uint64_t isolate_id = 0x20151021; |
| 266 | { |
| 267 | TRACE_EVENT_SCOPED_CONTEXT("v8-cat", "Isolate", isolate_id); |
| 268 | TRACE_EVENT0("v8-cat", "e"); |
| 269 | } |
| 270 | |
| 271 | CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->length()); |
| 272 | CHECK_EQ(TRACE_EVENT_PHASE_ENTER_CONTEXT, GET_TRACE_OBJECT(0)->phase); |
| 273 | CHECK_EQ("Isolate", GET_TRACE_OBJECT(0)->name); |
| 274 | CHECK_EQ(isolate_id, GET_TRACE_OBJECT(0)->id); |
| 275 | CHECK_EQ(TRACE_EVENT_PHASE_COMPLETE, GET_TRACE_OBJECT(1)->phase); |
| 276 | CHECK_EQ("e", GET_TRACE_OBJECT(1)->name); |
| 277 | CHECK_EQ(TRACE_EVENT_PHASE_LEAVE_CONTEXT, GET_TRACE_OBJECT(2)->phase); |
| 278 | CHECK_EQ("Isolate", GET_TRACE_OBJECT(2)->name); |
| 279 | CHECK_EQ(isolate_id, GET_TRACE_OBJECT(2)->id); |
| 280 | |
| 281 | i::V8::SetPlatformForTesting(old_platform); |
| 282 | } |