70a7c754bf
This is based on the Skia Implementation. More on the project can be found here: https://docs.google.com/a/chromium.org/document/d/1_4LAnInOB8tM_DLjptWiszRwa4qwiSsDzMkO4tU-Qes/edit#heading=h.p97rw6yt8o2j The V8 Tracing platform will replace the isolate->event_logger(). But since the current embedders (namely chromium) currently use the isolate->event_logger, I made the default implementation (event-tracer) call into isolate->event_logger if an event_logger was set. Once the embedders properly implement the interface (for example in chromium it would look like this: https://codereview.chromium.org/707273005/), the default implementation will be doing nothing. Once the embedders side is fixed, we will change how V8 uses the tracing framework beyond the call from Logger:CallEventLogger. (which would also include a d8 implementation) BUG=v8:4560 LOG=N Review URL: https://codereview.chromium.org/988893003 Cr-Commit-Position: refs/heads/master@{#32959}
259 lines
7.8 KiB
C++
259 lines
7.8 KiB
C++
// Copyright 2015 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.
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "src/v8.h"
|
|
|
|
#include "src/list.h"
|
|
#include "src/list-inl.h"
|
|
#include "test/cctest/cctest.h"
|
|
|
|
using v8::IdleTask;
|
|
using v8::Task;
|
|
using v8::Isolate;
|
|
|
|
#include "src/tracing/trace-event.h"
|
|
|
|
#define GET_TRACE_OBJECTS_LIST platform.GetMockTraceObjects()
|
|
|
|
#define GET_TRACE_OBJECT(Index) GET_TRACE_OBJECTS_LIST->at(Index)
|
|
|
|
|
|
struct MockTraceObject {
|
|
char phase;
|
|
std::string name;
|
|
uint64_t id;
|
|
uint64_t bind_id;
|
|
int num_args;
|
|
unsigned int flags;
|
|
MockTraceObject(char phase, std::string name, uint64_t id, uint64_t bind_id,
|
|
int num_args, int flags)
|
|
: phase(phase),
|
|
name(name),
|
|
id(id),
|
|
bind_id(bind_id),
|
|
num_args(num_args),
|
|
flags(flags) {}
|
|
};
|
|
|
|
typedef v8::internal::List<MockTraceObject*> MockTraceObjectList;
|
|
|
|
class MockTracingPlatform : public v8::Platform {
|
|
public:
|
|
explicit MockTracingPlatform(v8::Platform* platform) {}
|
|
virtual ~MockTracingPlatform() {
|
|
for (int i = 0; i < trace_object_list_.length(); ++i) {
|
|
delete trace_object_list_[i];
|
|
}
|
|
trace_object_list_.Clear();
|
|
}
|
|
void CallOnBackgroundThread(Task* task,
|
|
ExpectedRuntime expected_runtime) override {}
|
|
|
|
void CallOnForegroundThread(Isolate* isolate, Task* task) override {}
|
|
|
|
void CallDelayedOnForegroundThread(Isolate* isolate, Task* task,
|
|
double delay_in_seconds) override {}
|
|
|
|
double MonotonicallyIncreasingTime() override { return 0.0; }
|
|
|
|
void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) override {}
|
|
|
|
bool IdleTasksEnabled(Isolate* isolate) override { return false; }
|
|
|
|
bool PendingIdleTask() { return false; }
|
|
|
|
void PerformIdleTask(double idle_time_in_seconds) {}
|
|
|
|
bool PendingDelayedTask() { return false; }
|
|
|
|
void PerformDelayedTask() {}
|
|
|
|
uint64_t AddTraceEvent(char phase, const uint8_t* category_enabled_flag,
|
|
const char* name, 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) override {
|
|
MockTraceObject* to = new MockTraceObject(phase, std::string(name), id,
|
|
bind_id, num_args, flags);
|
|
trace_object_list_.Add(to);
|
|
return 0;
|
|
}
|
|
|
|
void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
|
|
const char* name, uint64_t handle) override {}
|
|
|
|
const uint8_t* GetCategoryGroupEnabled(const char* name) override {
|
|
if (strcmp(name, "v8-cat")) {
|
|
static uint8_t no = 0;
|
|
return &no;
|
|
} else {
|
|
static uint8_t yes = 0x7;
|
|
return &yes;
|
|
}
|
|
}
|
|
|
|
const char* GetCategoryGroupName(
|
|
const uint8_t* category_enabled_flag) override {
|
|
static const char dummy[] = "dummy";
|
|
return dummy;
|
|
}
|
|
|
|
MockTraceObjectList* GetMockTraceObjects() { return &trace_object_list_; }
|
|
|
|
private:
|
|
MockTraceObjectList trace_object_list_;
|
|
};
|
|
|
|
|
|
TEST(TraceEventDisabledCategory) {
|
|
v8::Platform* old_platform = i::V8::GetCurrentPlatform();
|
|
MockTracingPlatform platform(old_platform);
|
|
i::V8::SetPlatformForTesting(&platform);
|
|
|
|
// Disabled category, will not add events.
|
|
TRACE_EVENT_BEGIN0("cat", "e1");
|
|
TRACE_EVENT_END0("cat", "e1");
|
|
CHECK_EQ(0, GET_TRACE_OBJECTS_LIST->length());
|
|
|
|
i::V8::SetPlatformForTesting(old_platform);
|
|
}
|
|
|
|
|
|
TEST(TraceEventNoArgs) {
|
|
v8::Platform* old_platform = i::V8::GetCurrentPlatform();
|
|
MockTracingPlatform platform(old_platform);
|
|
i::V8::SetPlatformForTesting(&platform);
|
|
|
|
// Enabled category will add 2 events.
|
|
TRACE_EVENT_BEGIN0("v8-cat", "e1");
|
|
TRACE_EVENT_END0("v8-cat", "e1");
|
|
|
|
CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->length());
|
|
CHECK_EQ('B', GET_TRACE_OBJECT(0)->phase);
|
|
CHECK_EQ("e1", GET_TRACE_OBJECT(0)->name);
|
|
CHECK_EQ(0, GET_TRACE_OBJECT(0)->num_args);
|
|
|
|
CHECK_EQ('E', GET_TRACE_OBJECT(1)->phase);
|
|
CHECK_EQ("e1", GET_TRACE_OBJECT(1)->name);
|
|
CHECK_EQ(0, GET_TRACE_OBJECT(1)->num_args);
|
|
|
|
i::V8::SetPlatformForTesting(old_platform);
|
|
}
|
|
|
|
|
|
TEST(TraceEventWithOneArg) {
|
|
v8::Platform* old_platform = i::V8::GetCurrentPlatform();
|
|
MockTracingPlatform platform(old_platform);
|
|
i::V8::SetPlatformForTesting(&platform);
|
|
|
|
TRACE_EVENT_BEGIN1("v8-cat", "e1", "arg1", 42);
|
|
TRACE_EVENT_END1("v8-cat", "e1", "arg1", 42);
|
|
TRACE_EVENT_BEGIN1("v8-cat", "e2", "arg1", "abc");
|
|
TRACE_EVENT_END1("v8-cat", "e2", "arg1", "abc");
|
|
|
|
CHECK_EQ(4, GET_TRACE_OBJECTS_LIST->length());
|
|
|
|
CHECK_EQ(1, GET_TRACE_OBJECT(0)->num_args);
|
|
CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args);
|
|
CHECK_EQ(1, GET_TRACE_OBJECT(2)->num_args);
|
|
CHECK_EQ(1, GET_TRACE_OBJECT(3)->num_args);
|
|
|
|
i::V8::SetPlatformForTesting(old_platform);
|
|
}
|
|
|
|
|
|
TEST(TraceEventWithTwoArgs) {
|
|
v8::Platform* old_platform = i::V8::GetCurrentPlatform();
|
|
MockTracingPlatform platform(old_platform);
|
|
i::V8::SetPlatformForTesting(&platform);
|
|
|
|
TRACE_EVENT_BEGIN2("v8-cat", "e1", "arg1", 42, "arg2", "abc");
|
|
TRACE_EVENT_END2("v8-cat", "e1", "arg1", 42, "arg2", "abc");
|
|
TRACE_EVENT_BEGIN2("v8-cat", "e2", "arg1", "abc", "arg2", 43);
|
|
TRACE_EVENT_END2("v8-cat", "e2", "arg1", "abc", "arg2", 43);
|
|
|
|
CHECK_EQ(4, GET_TRACE_OBJECTS_LIST->length());
|
|
|
|
CHECK_EQ(2, GET_TRACE_OBJECT(0)->num_args);
|
|
CHECK_EQ(2, GET_TRACE_OBJECT(1)->num_args);
|
|
CHECK_EQ(2, GET_TRACE_OBJECT(2)->num_args);
|
|
CHECK_EQ(2, GET_TRACE_OBJECT(3)->num_args);
|
|
|
|
i::V8::SetPlatformForTesting(old_platform);
|
|
}
|
|
|
|
|
|
TEST(ScopedTraceEvent) {
|
|
v8::Platform* old_platform = i::V8::GetCurrentPlatform();
|
|
MockTracingPlatform platform(old_platform);
|
|
i::V8::SetPlatformForTesting(&platform);
|
|
|
|
{ TRACE_EVENT0("v8-cat", "e"); }
|
|
|
|
CHECK_EQ(1, GET_TRACE_OBJECTS_LIST->length());
|
|
CHECK_EQ(0, GET_TRACE_OBJECT(0)->num_args);
|
|
|
|
{ TRACE_EVENT1("v8-cat", "e1", "arg1", "abc"); }
|
|
|
|
CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->length());
|
|
CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args);
|
|
|
|
{ TRACE_EVENT2("v8-cat", "e1", "arg1", "abc", "arg2", 42); }
|
|
|
|
CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->length());
|
|
CHECK_EQ(2, GET_TRACE_OBJECT(2)->num_args);
|
|
|
|
i::V8::SetPlatformForTesting(old_platform);
|
|
}
|
|
|
|
|
|
TEST(TestEventWithFlow) {
|
|
v8::Platform* old_platform = i::V8::GetCurrentPlatform();
|
|
MockTracingPlatform platform(old_platform);
|
|
i::V8::SetPlatformForTesting(&platform);
|
|
|
|
static uint64_t bind_id = 21;
|
|
{
|
|
TRACE_EVENT_WITH_FLOW0("v8-cat", "f1", bind_id, TRACE_EVENT_FLAG_FLOW_OUT);
|
|
}
|
|
{
|
|
TRACE_EVENT_WITH_FLOW0(
|
|
"v8-cat", "f2", bind_id,
|
|
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
|
|
}
|
|
{ TRACE_EVENT_WITH_FLOW0("v8-cat", "f3", bind_id, TRACE_EVENT_FLAG_FLOW_IN); }
|
|
|
|
CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->length());
|
|
CHECK_EQ(bind_id, GET_TRACE_OBJECT(0)->bind_id);
|
|
CHECK_EQ(TRACE_EVENT_FLAG_FLOW_OUT, GET_TRACE_OBJECT(0)->flags);
|
|
CHECK_EQ(bind_id, GET_TRACE_OBJECT(1)->bind_id);
|
|
CHECK_EQ(TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
|
|
GET_TRACE_OBJECT(1)->flags);
|
|
CHECK_EQ(bind_id, GET_TRACE_OBJECT(2)->bind_id);
|
|
CHECK_EQ(TRACE_EVENT_FLAG_FLOW_IN, GET_TRACE_OBJECT(2)->flags);
|
|
|
|
i::V8::SetPlatformForTesting(old_platform);
|
|
}
|
|
|
|
|
|
TEST(TestEventWithId) {
|
|
v8::Platform* old_platform = i::V8::GetCurrentPlatform();
|
|
MockTracingPlatform platform(old_platform);
|
|
i::V8::SetPlatformForTesting(&platform);
|
|
|
|
static uint64_t event_id = 21;
|
|
TRACE_EVENT_ASYNC_BEGIN0("v8-cat", "a1", event_id);
|
|
TRACE_EVENT_ASYNC_END0("v8-cat", "a1", event_id);
|
|
|
|
CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->length());
|
|
CHECK_EQ(TRACE_EVENT_PHASE_ASYNC_BEGIN, GET_TRACE_OBJECT(0)->phase);
|
|
CHECK_EQ(event_id, GET_TRACE_OBJECT(0)->id);
|
|
CHECK_EQ(TRACE_EVENT_PHASE_ASYNC_END, GET_TRACE_OBJECT(1)->phase);
|
|
CHECK_EQ(event_id, GET_TRACE_OBJECT(1)->id);
|
|
|
|
i::V8::SetPlatformForTesting(old_platform);
|
|
}
|