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

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

Issue 422593003: Initial GetSample implementation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Made the Sample class into an iterable. 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
« src/sampler.cc ('K') | « test/cctest/test-log-stack-tracer.cc ('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
11 #include "src/v8.h"
alph 2014/09/08 12:47:40 style: no need for extra lines between includes.
gholap 2014/09/08 23:57:38 Done.
12
13 #include "src/base/platform/platform.h"
14
15 #include "test/cctest/cctest.h"
16
17 using v8::Local;
18
19 namespace {
20 // Sampler thread waits on this semaphore.
21 v8::base::Semaphore* sampler_semaphore = new v8::base::Semaphore(0);
22
23 // V8 thread (the JavaScript code) waits on this semaphore.
24 v8::base::Semaphore* v8_semaphore = new v8::base::Semaphore(0);
25
26 // The JavaScript calls this function when on full stack depth.
27 void SignalAndWaitForSampler(
28 const v8::FunctionCallbackInfo<v8::Value>& args) {
29 // Tell the sampler that it can take a sample now.
30 sampler_semaphore->Signal();
31
32 // Wait for the sampler to finish collecting a sample.
33 v8_semaphore->Wait();
34 }
35 }
36
37
38 // A thread which collects samples from v8.
39 class V8_FINAL SamplerThread : public v8::base::Thread {
40 public:
41 explicit SamplerThread(v8::Isolate* isolate)
42 : Thread(v8::base::Thread::Options("sampler-api-tester")),
43 isolate_(isolate) {
44 }
45
46 virtual ~SamplerThread() {}
47
48 virtual void Run() {
49 sampler_semaphore->Wait(); // Wait for JS to reach full stack depth.
50 isolate_->GetSample(&sample);
51 v8_semaphore->Signal(); // Tell JS that sample collection is done.
52 }
53
54 v8::Sample sample;
55
56 private:
57 v8::Isolate* isolate_;
58 };
59
60
61 // A JavaScript function which takes stack depth
62 // (minimum value 2) as an argument.
63 // When at the bottom of the recursion,
64 // the JavaScript code calls into C++ test code,
65 // waiting for the sampler to take a sample.
66 static const char* sampler_api_test_function = "function func(depth) {"
67 " if (depth == 2) SignalAndWaitForSampler();"
68 " else return func(depth - 1);"
69 "}";
70
71
72 TEST(StackDepthIsConsistent) {
73 v8::Isolate* isolate = CcTest::isolate();
74 v8::HandleScope scope(isolate);
75 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
76 global->Set(
77 v8::String::NewFromUtf8(isolate, "SignalAndWaitForSampler"),
78 v8::FunctionTemplate::New(isolate, SignalAndWaitForSampler));
79
80 LocalContext env(isolate, NULL, global);
81 std::string source(sampler_api_test_function);
82 source.append("func(8);");
83 Local<v8::Script> script = v8::Script::Compile(
84 v8::String::NewFromUtf8(isolate, source.c_str()));
85 SamplerThread sampler(isolate);
86
87 sampler.Start();
88 script->Run();
89 sampler.Join();
90
91 CHECK_EQ(8, sampler.sample.size());
92 }
93
94
95 TEST(StackDepthDoesNotExceedMaxValue) {
96 v8::Isolate* isolate = CcTest::isolate();
97 v8::HandleScope scope(isolate);
98 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
99 global->Set(
100 v8::String::NewFromUtf8(isolate, "SignalAndWaitForSampler"),
101 v8::FunctionTemplate::New(isolate, SignalAndWaitForSampler));
102
103 LocalContext env(isolate, NULL, global);
104 std::string source(sampler_api_test_function);
105 source.append("func(300);");
106 Local<v8::Script> script = v8::Script::Compile(
107 v8::String::NewFromUtf8(isolate, source.c_str()));
108 SamplerThread sampler(isolate);
109
110 sampler.Start();
111 script->Run();
112 sampler.Join();
113
114 int MAX_SIZE = v8::Sample::kMaxSize;
115 CHECK_EQ(MAX_SIZE, sampler.sample.size());
116 }
117
118
119 namespace {
120 std::vector<v8::JitCodeEvent> inner_funcs;
121 std::vector<v8::JitCodeEvent> outer_funcs;
122
123 void TestJitCodeEventHandler(const v8::JitCodeEvent* event) {
124 if (event->type != v8::JitCodeEvent::CODE_ADDED) return;
125 std::string name(event->name.str, event->name.len);
126 if (name.find("test_sampler_api_inner") != std::string::npos)
127 inner_funcs.push_back(*event);
128 if (name.find("test_sampler_api_outer") != std::string::npos)
129 outer_funcs.push_back(*event);
130 }
131 }
132
133
134 // Note: The argumnets.callee stuff is there so that the
135 // functions are not optimized away.
136 static const char* sampler_api_test_script =
137 "function test_sampler_api_inner() {"
138 " SignalAndWaitForSampler();"
139 " return arguments.callee.toString();"
140 "}"
141 "function test_sampler_api_outer() {"
142 " return test_sampler_api_inner() + arguments.callee.toString();"
143 "}"
144 "test_sampler_api_outer();";
145
146
147 // The captured sample should have three pc values.
148 // They should fall in the range where the compiled code
149 // The expected stack is:
150 // bottom of stack [{anon script}, outer, inner] top of stack
151 // ^ ^ ^
152 // sample.stack indices 2 1 0
153 TEST(StackFramesConsistent) {
154 v8::Isolate* isolate = CcTest::isolate();
155 v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault,
156 TestJitCodeEventHandler);
157 v8::HandleScope scope(isolate);
158 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
159 global->Set(
160 v8::String::NewFromUtf8(isolate, "SignalAndWaitForSampler"),
161 v8::FunctionTemplate::New(isolate, SignalAndWaitForSampler));
162
163 LocalContext env(isolate, NULL, global);
164 Local<v8::Script> script = v8::Script::Compile(
165 v8::String::NewFromUtf8(isolate, sampler_api_test_script));
166 SamplerThread sampler(isolate);
167
168 sampler.Start();
169 script->Run();
170 sampler.Join();
171
172 CHECK_EQ(3, sampler.sample.size());
173
174 bool stack_top_is_inner = false;
175 bool below_inner_is_outer = false;
176
177 for (unsigned i = 0; i < inner_funcs.size(); i++) {
178 void* start_addr = inner_funcs[i].code_start;
179 void* end_addr = reinterpret_cast<void*>((int64_t)inner_funcs[i].code_start
180 + inner_funcs[i].code_len);
181 if ((*sampler.sample.begin() >= start_addr) &&
182 (*sampler.sample.begin() < end_addr))
183 stack_top_is_inner = true;
184 }
185
186 for (unsigned i = 0; i < outer_funcs.size(); i++) {
187 void* start_addr = outer_funcs[i].code_start;
188 void* end_addr = reinterpret_cast<void*>((int64_t)outer_funcs[i].code_start
189 + outer_funcs[i].code_len);
190 if ((*(sampler.sample.begin() + 1) >= start_addr) &&
191 (*(sampler.sample.begin() + 1) < end_addr))
192 below_inner_is_outer = true;
193 }
194
195 CHECK_EQ(true, stack_top_is_inner);
196 CHECK_EQ(true, below_inner_is_outer);
197 }
OLDNEW
« src/sampler.cc ('K') | « test/cctest/test-log-stack-tracer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698