Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Side by Side Diff: test/cctest/test-sampler-api.cc

Issue 519543002: [WIP] Added CodeEventListener to the sampler API. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: CallbackEvent also logs as code-creation, added coverage for that. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/cctest/cctest.gyp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 //
5 // Tests the public sampling API in include/v8.h
6
7 #include <string>
8
9 #include "include/v8.h"
10 #include "include/v8stdint.h"
11
12 #include "src/v8.h"
13
14 #include "src/base/platform/platform.h"
15
16 #include "test/cctest/cctest.h"
17
18 using v8::Local;
19
20 namespace {
21 // Sampler thread waits on this semaphore.
22 v8::base::Semaphore* SamplerSemaphore = new v8::base::Semaphore(0);
23
24 // V8 thread (the JavaScript code) waits on this semaphore.
25 v8::base::Semaphore* V8Semaphore = new v8::base::Semaphore(0);
26
27 // The JavaScript calls this function when on full stack depth.
28 void SignalAndWaitForSampler(
29 const v8::FunctionCallbackInfo<v8::Value>& args) {
30 // Tell the sampler that it can take a sample now.
31 SamplerSemaphore->Signal();
32
33 // Wait for the sampler to finish collecting a sample.
34 V8Semaphore->Wait();
35 }
36 }
37
38
39 // A thread which collects samples from v8.
40 class V8_FINAL SamplerThread : public v8::base::Thread {
41 public:
42 explicit SamplerThread(v8::Isolate* isolate)
43 : Thread(v8::base::Thread::Options("sampler-api-tester")),
44 isolate_(isolate) {
45 }
46
47 virtual ~SamplerThread() {}
48
49 virtual void Run() {
50 SamplerSemaphore->Wait(); // Wait for JS to reach full stack depth.
51 isolate_->GetSample(&sample);
52 V8Semaphore->Signal(); // Tell JS that sample collection is done.
53 }
54
55 v8::Sample sample;
56
57 private:
58 v8::Isolate* isolate_;
59 };
60
61
62 // A JavaScript function which takes stack depth
63 // (minimum value 2) as an argument.
64 // When at the bottom of the recursion,
65 // the JavaScript code calls into C++ test code,
66 // waiting for the sampler to take a sample.
67 static const char* sampler_api_test_function = "function func(depth) {"
68 " if (depth == 2) SignalAndWaitForSampler();"
69 " else return func(depth - 1);"
70 "}";
71
72
73 // TODO(gholap): Right now, we are just checking whether GetSample
74 // gets samples and whether the stack depth is reasonable.
75 // After implementing code event listener API, add tests
76 // to further verify the correctness of collected samples.
77 TEST(StackDepthIsConsistent) {
78 v8::Isolate* isolate = CcTest::isolate();
79 v8::HandleScope scope(isolate);
80 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
81 global->Set(
82 v8::String::NewFromUtf8(isolate, "SignalAndWaitForSampler"),
83 v8::FunctionTemplate::New(isolate, SignalAndWaitForSampler));
84
85 LocalContext env(isolate, NULL, global);
86 std::string source(sampler_api_test_function);
87 source.append("func(8);");
88 Local<v8::Script> script = v8::Script::Compile(
89 v8::String::NewFromUtf8(isolate, source.c_str()));
90 SamplerThread sampler(isolate);
91
92 sampler.Start();
93 script->Run();
94 sampler.Join();
95
96 CHECK_EQ(8, sampler.sample.frames_count);
97 }
98
99
100 TEST(StackDepthDoesNotExceedMaxValue) {
101 v8::Isolate* isolate = CcTest::isolate();
102 v8::HandleScope scope(isolate);
103 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
104 global->Set(
105 v8::String::NewFromUtf8(isolate, "SignalAndWaitForSampler"),
106 v8::FunctionTemplate::New(isolate, SignalAndWaitForSampler));
107
108 LocalContext env(isolate, NULL, global);
109 std::string source(sampler_api_test_function);
110 source.append("func(300);");
111 Local<v8::Script> script = v8::Script::Compile(
112 v8::String::NewFromUtf8(isolate, source.c_str()));
113 SamplerThread sampler(isolate);
114
115 sampler.Start();
116 script->Run();
117 sampler.Join();
118
119 int MAX_FRAMES_COUNT = v8::Sample::kMaxFramesCount;
120 CHECK_EQ(MAX_FRAMES_COUNT, sampler.sample.frames_count);
121 }
122
123
124 namespace {
125 class TestCodeEventHandler : public v8::CodeEventHandler {
126 public:
127 virtual void Create(const void* from,
128 const int size,
129 const std::string& name) {
130 if (name.find("outer") == 0) {
131 outer_starts.push_back(from);
132 outer_ends.push_back((const void*)((int64_t)from + size));
133 } else if (name.find("inner") == 0) {
134 inner_starts.push_back(from);
135 inner_ends.push_back((const void*)((int64_t)from + size));
136 }
137 }
138
139 virtual void Delete(const void* from) {}
140 virtual void Move(const void* from, const void* to) {}
141 virtual void SharedLibrary(const std::string& library_path,
142 const void* start,
143 const void* end) {}
144
145 std::vector<const void*> outer_starts;
146 std::vector<const void*> outer_ends;
147 std::vector<const void*> inner_starts;
148 std::vector<const void*> inner_ends;
149 };
150 }
151
152
153 // Note: The argumnets.callee stuff is there so that the
154 // functions are not optimized away.
155 static const char* sampler_api_test_script =
156 "function inner() {"
157 " SignalAndWaitForSampler();"
158 " return arguments.callee.toString();"
159 "}"
160 "function outer() {return inner() + arguments.callee.toString()}"
161 "outer();";
162
163
164 // The captured sample should have three pc values.
165 // They should fall in the range where the compiled code
166 // The expected stack is:
167 // bottom of stack [{anon script}, outer, inner] top of stack
168 // ^ ^ ^
169 // sample.stack indices 2 1 0
170 TEST(StackFramesConsistent) {
171 v8::Isolate* isolate = CcTest::isolate();
172 TestCodeEventHandler code_event_handler;
173 isolate->InstallCodeEventHandler(&code_event_handler);
174 v8::HandleScope scope(isolate);
175 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
176 global->Set(
177 v8::String::NewFromUtf8(isolate, "SignalAndWaitForSampler"),
178 v8::FunctionTemplate::New(isolate, SignalAndWaitForSampler));
179
180 LocalContext env(isolate, NULL, global);
181 Local<v8::Script> script = v8::Script::Compile(
182 v8::String::NewFromUtf8(isolate, sampler_api_test_script));
183 SamplerThread sampler(isolate);
184
185 sampler.Start();
186 script->Run();
187 sampler.Join();
188
189 CHECK_EQ(3, sampler.sample.frames_count);
190
191 bool stack_top_is_inner = false;
192 bool below_inner_is_outer = false;
193
194 for (unsigned i = 0; i < code_event_handler.inner_starts.size(); i++) {
195 if ((sampler.sample.stack[0] >= code_event_handler.inner_starts[i]) &&
196 (sampler.sample.stack[0] < code_event_handler.inner_ends[i]))
197 stack_top_is_inner = true;
198 }
199
200 for (unsigned i = 0; i < code_event_handler.outer_starts.size(); i++) {
201 if ((sampler.sample.stack[1] >= code_event_handler.outer_starts[i]) &&
202 (sampler.sample.stack[1] < code_event_handler.outer_ends[i]))
203 below_inner_is_outer = true;
204 }
205
206 CHECK_EQ(true, stack_top_is_inner);
207 CHECK_EQ(true, below_inner_is_outer);
208 }
OLDNEW
« no previous file with comments | « test/cctest/cctest.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698