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

Unified Diff: test/cctest/test-sampler-api.cc

Issue 578163002: Implemented GetSample. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Including win32-headers.h in v8.h for testing on trybots. 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 side-by-side diff with in-line comments
Download patch
« src/sampler.h ('K') | « test/cctest/cctest.gyp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-sampler-api.cc
diff --git a/test/cctest/test-sampler-api.cc b/test/cctest/test-sampler-api.cc
new file mode 100644
index 0000000000000000000000000000000000000000..df2c074a979ac919e771d81539b68cb5594e161e
--- /dev/null
+++ b/test/cctest/test-sampler-api.cc
@@ -0,0 +1,169 @@
+// Copyright 2014 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.
+//
+// Tests the sampling API in include/v8.h
+
+#include <string>
+#include "include/v8.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#if V8_OS_POSIX && !V8_OS_CYGWIN
+#include <ucontext.h>
+#elif V8_OS_WIN || V8_OS_CYGWIN
+#include "src/base/win32-headers.h"
+#endif
+
+using v8::Local;
+
+namespace {
+// The Sample which CollectSample fills up
+v8::Sample* sample;
+
+// The isolate used in the test
+v8::Isolate* isolate;
+
+// Forward declaration
+// (platform specific implementation at the bottom of this file)
+v8::RegisterState GetRegisterState();
+
+// The JavaScript calls this function when on full stack depth.
+void CollectSample(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ isolate->GetSample(GetRegisterState(), sample);
+}
+
+
+// A JavaScript function which takes stack depth
+// (minimum value 2) as an argument.
+// When at the bottom of the recursion,
+// the JavaScript code calls into C++ test code,
+// waiting for the sampler to take a sample.
+static const char* test_function =
+ "function func(depth) {"
+ " if (depth == 2) CollectSample();"
+ " else return func(depth - 1);"
+ "}";
+}
alph 2014/09/19 11:43:05 nit: } // namespace
+
+
+#define SAMPLER_API_TESTS_BOOTSTRAP() \
+ v8::Sample sample_; \
+ sample = &sample_; \
+ isolate = CcTest::isolate(); \
+ v8::HandleScope scope(isolate); \
+ v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); \
+ global->Set(v8::String::NewFromUtf8(isolate, "CollectSample"), \
+ v8::FunctionTemplate::New(isolate, CollectSample)); \
+ LocalContext env(isolate, NULL, global)
+
+
+TEST(StackDepthIsConsistent) {
+ SAMPLER_API_TESTS_BOOTSTRAP();
+
+ std::string source(test_function);
+ source.append("func(8);");
+ v8::Script::Compile(v8::String::NewFromUtf8(isolate, source.c_str()))->Run();
+
+ CHECK_EQ(8, sample->size());
+}
+
+
+TEST(StackDepthDoesNotExceedMaxValue) {
+ SAMPLER_API_TESTS_BOOTSTRAP();
+
+ std::string source(test_function);
+ source.append("func(300);");
+ v8::Script::Compile(v8::String::NewFromUtf8(isolate, source.c_str()))->Run();
+
+ int MAX_SIZE = v8::Sample::kMaxSize;
+ CHECK_EQ(MAX_SIZE, sample->size());
+}
+
+
+namespace {
+std::vector<v8::JitCodeEvent> inner_funcs;
+std::vector<v8::JitCodeEvent> outer_funcs;
+
+void TestJitCodeEventHandler(const v8::JitCodeEvent* event) {
+ if (event->type != v8::JitCodeEvent::CODE_ADDED) return;
+ std::string name(event->name.str, event->name.len);
+ if (name.find("test_sampler_api_inner") != std::string::npos)
+ inner_funcs.push_back(*event);
+ if (name.find("test_sampler_api_outer") != std::string::npos)
+ outer_funcs.push_back(*event);
+}
+
+
+// Note: The arguments.callee stuff is there so that the
+// functions are not optimized away.
+static const char* test_script =
+ "function test_sampler_api_inner() {"
+ " CollectSample();"
+ " return arguments.callee.toString();"
+ "}"
+ "function test_sampler_api_outer() {"
+ " return test_sampler_api_inner() + arguments.callee.toString();"
+ "}"
+ "test_sampler_api_outer();";
+}
alph 2014/09/19 11:43:05 ditto
+
+
+// The captured sample should have three pc values.
+// They should fall in the range where the compiled code
+// The expected stack is:
+// bottom of stack [{anon script}, outer, inner] top of stack
+// ^ ^ ^
+// sample.stack indices 2 1 0
+TEST(StackFramesConsistent) {
+ SAMPLER_API_TESTS_BOOTSTRAP();
+
+ v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault,
+ TestJitCodeEventHandler);
+ v8::Script::Compile(v8::String::NewFromUtf8(isolate, test_script))->Run();
+
+ CHECK_EQ(3, sample->size());
+
+ bool stack_top_is_inner = false;
+ bool below_inner_is_outer = false;
+
+ for (unsigned i = 0; i < inner_funcs.size(); i++) {
+ void* start_addr = inner_funcs[i].code_start;
+ void* end_addr = reinterpret_cast<void*>(
+ (int64_t)inner_funcs[i].code_start + inner_funcs[i].code_len);
+ if ((*sample->begin() >= start_addr) && (*sample->begin() < end_addr))
+ stack_top_is_inner = true;
+ }
+
+ for (unsigned i = 0; i < outer_funcs.size(); i++) {
+ void* start_addr = outer_funcs[i].code_start;
+ void* end_addr = reinterpret_cast<void*>(
+ (int64_t)outer_funcs[i].code_start + outer_funcs[i].code_len);
+ if ((*(sample->begin() + 1) >= start_addr) &&
+ (*(sample->begin() + 1) < end_addr))
+ below_inner_is_outer = true;
+ }
+
+ CHECK(stack_top_is_inner);
+ CHECK(below_inner_is_outer);
+}
+
+
+// Platform specific implementation of GetStackAndFramePointers
+namespace {
+v8::RegisterState GetRegisterState() {
+#if V8_OS_POSIX && !V8_OS_CYGWIN
+ ucontext_t context;
+ getcontext(&context);
+#elif V8_OS_WIN || V8_OS_CYGWIN
+ CONTEXT context;
+ memset(&context, 0, sizeof(context));
+ context.ContextFlags = CONTEXT_FULL;
+ GetThreadContext(OpenThread(THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME |
+ THREAD_QUERY_INFORMATION,
+ false, GetCurrentThreadId()),
+ &context);
+#endif // V8_OS_POSIX && !V8_OS_CYGWIN / V8_OS_WIN || V8_OS_CYGWIN
+ return v8::RegisterState(context);
+}
+}
alph 2014/09/19 11:43:05 ditto
« src/sampler.h ('K') | « test/cctest/cctest.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698