OLD | NEW |
(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" |
| 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 // TODO(gholap): Right now, we are just checking whether GetSample |
| 73 // gets samples and whether the stack depth is reasonable. |
| 74 // After implementing code event listener API, add tests |
| 75 // to further verify the correctness of collected samples. |
| 76 TEST(StackDepthIsConsistent) { |
| 77 v8::Isolate* isolate = CcTest::isolate(); |
| 78 v8::HandleScope scope(isolate); |
| 79 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); |
| 80 global->Set( |
| 81 v8::String::NewFromUtf8(isolate, "SignalAndWaitForSampler"), |
| 82 v8::FunctionTemplate::New(isolate, SignalAndWaitForSampler)); |
| 83 |
| 84 LocalContext env(isolate, NULL, global); |
| 85 std::string source(sampler_api_test_function); |
| 86 source.append("func(8);"); |
| 87 Local<v8::Script> script = v8::Script::Compile( |
| 88 v8::String::NewFromUtf8(isolate, source.c_str())); |
| 89 SamplerThread sampler(isolate); |
| 90 |
| 91 sampler.Start(); |
| 92 script->Run(); |
| 93 sampler.Join(); |
| 94 |
| 95 CHECK_EQ(8, sampler.sample.frames_count); |
| 96 } |
| 97 |
| 98 |
| 99 TEST(StackDepthDoesNotExceedMaxValue) { |
| 100 v8::Isolate* isolate = CcTest::isolate(); |
| 101 v8::HandleScope scope(isolate); |
| 102 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); |
| 103 global->Set( |
| 104 v8::String::NewFromUtf8(isolate, "SignalAndWaitForSampler"), |
| 105 v8::FunctionTemplate::New(isolate, SignalAndWaitForSampler)); |
| 106 |
| 107 LocalContext env(isolate, NULL, global); |
| 108 std::string source(sampler_api_test_function); |
| 109 source.append("func(300);"); |
| 110 Local<v8::Script> script = v8::Script::Compile( |
| 111 v8::String::NewFromUtf8(isolate, source.c_str())); |
| 112 SamplerThread sampler(isolate); |
| 113 |
| 114 sampler.Start(); |
| 115 script->Run(); |
| 116 sampler.Join(); |
| 117 |
| 118 int MAX_FRAMES_COUNT = v8::Sample::kMaxFramesCount; |
| 119 CHECK_EQ(MAX_FRAMES_COUNT, sampler.sample.frames_count); |
| 120 } |
OLD | NEW |