Line data Source code
1 : // Copyright 2016 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 : // Tests of sampler functionalities.
5 :
6 : #include "src/libsampler/sampler.h"
7 :
8 : #include "src/base/platform/platform.h"
9 : #include "src/base/platform/time.h"
10 : #include "test/cctest/cctest.h"
11 :
12 :
13 : namespace v8 {
14 : namespace sampler {
15 :
16 : namespace {
17 :
18 0 : class TestSamplingThread : public base::Thread {
19 : public:
20 : static const int kSamplerThreadStackSize = 64 * 1024;
21 :
22 : explicit TestSamplingThread(Sampler* sampler)
23 : : Thread(base::Thread::Options("TestSamplingThread",
24 : kSamplerThreadStackSize)),
25 0 : sampler_(sampler) {}
26 :
27 : // Implement Thread::Run().
28 0 : void Run() override {
29 0 : while (sampler_->IsProfiling()) {
30 0 : sampler_->DoSample();
31 0 : base::OS::Sleep(base::TimeDelta::FromMilliseconds(1));
32 : }
33 0 : }
34 :
35 : private:
36 : Sampler* sampler_;
37 : };
38 :
39 :
40 0 : class TestSampler : public Sampler {
41 : public:
42 0 : explicit TestSampler(Isolate* isolate) : Sampler(isolate) {}
43 :
44 0 : void SampleStack(const v8::RegisterState& regs) override {
45 : void* frames[kMaxFramesCount];
46 : SampleInfo sample_info;
47 0 : isolate()->GetStackSample(regs, frames, kMaxFramesCount, &sample_info);
48 0 : if (is_counting_samples_) {
49 0 : if (sample_info.vm_state == JS) ++js_sample_count_;
50 0 : if (sample_info.vm_state == EXTERNAL) ++external_sample_count_;
51 : }
52 0 : }
53 : };
54 :
55 :
56 : class TestApiCallbacks {
57 : public:
58 : TestApiCallbacks() = default;
59 :
60 0 : static void Getter(v8::Local<v8::String> name,
61 : const v8::PropertyCallbackInfo<v8::Value>& info) {
62 0 : }
63 :
64 0 : static void Setter(v8::Local<v8::String> name,
65 : v8::Local<v8::Value> value,
66 : const v8::PropertyCallbackInfo<void>& info) {
67 0 : }
68 : };
69 :
70 :
71 0 : static void RunSampler(v8::Local<v8::Context> env,
72 : v8::Local<v8::Function> function,
73 : v8::Local<v8::Value> argv[], int argc,
74 : unsigned min_js_samples = 0,
75 : unsigned min_external_samples = 0) {
76 0 : Sampler::SetUp();
77 0 : TestSampler* sampler = new TestSampler(env->GetIsolate());
78 0 : TestSamplingThread* thread = new TestSamplingThread(sampler);
79 0 : sampler->IncreaseProfilingDepth();
80 0 : sampler->Start();
81 : sampler->StartCountingSamples();
82 0 : thread->StartSynchronously();
83 0 : do {
84 0 : function->Call(env, env->Global(), argc, argv).ToLocalChecked();
85 0 : } while (sampler->js_sample_count() < min_js_samples ||
86 : sampler->external_sample_count() < min_external_samples);
87 0 : sampler->Stop();
88 0 : sampler->DecreaseProfilingDepth();
89 0 : thread->Join();
90 0 : delete thread;
91 0 : delete sampler;
92 0 : Sampler::TearDown();
93 0 : }
94 :
95 : } // namespace
96 :
97 : static const char* sampler_test_source = "function start(count) {\n"
98 : " for (var i = 0; i < count; i++) {\n"
99 : " var o = instance.foo;\n"
100 : " instance.foo = o + 1;\n"
101 : " }\n"
102 : "}\n";
103 :
104 0 : static v8::Local<v8::Function> GetFunction(v8::Local<v8::Context> env,
105 : const char* name) {
106 : return v8::Local<v8::Function>::Cast(
107 0 : env->Global()->Get(env, v8_str(name)).ToLocalChecked());
108 : }
109 :
110 :
111 28337 : TEST(LibSamplerCollectSample) {
112 0 : LocalContext env;
113 0 : v8::Isolate* isolate = env->GetIsolate();
114 0 : v8::HandleScope scope(isolate);
115 :
116 : v8::Local<v8::FunctionTemplate> func_template =
117 0 : v8::FunctionTemplate::New(isolate);
118 : v8::Local<v8::ObjectTemplate> instance_template =
119 0 : func_template->InstanceTemplate();
120 :
121 : TestApiCallbacks accessors;
122 : v8::Local<v8::External> data =
123 0 : v8::External::New(isolate, &accessors);
124 : instance_template->SetAccessor(v8_str("foo"), &TestApiCallbacks::Getter,
125 0 : &TestApiCallbacks::Setter, data);
126 : v8::Local<v8::Function> func =
127 0 : func_template->GetFunction(env.local()).ToLocalChecked();
128 : v8::Local<v8::Object> instance =
129 0 : func->NewInstance(env.local()).ToLocalChecked();
130 0 : env->Global()->Set(env.local(), v8_str("instance"), instance).FromJust();
131 :
132 0 : CompileRun(sampler_test_source);
133 0 : v8::Local<v8::Function> function = GetFunction(env.local(), "start");
134 :
135 : int32_t repeat_count = 100;
136 0 : v8::Local<v8::Value> args[] = {v8::Integer::New(isolate, repeat_count)};
137 0 : RunSampler(env.local(), function, args, arraysize(args), 100, 100);
138 0 : }
139 :
140 : } // namespace sampler
141 85011 : } // namespace v8
|