summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-cpu-profiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/test-cpu-profiler.cc')
-rw-r--r--deps/v8/test/cctest/test-cpu-profiler.cc333
1 files changed, 264 insertions, 69 deletions
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index e08bec375e..3a3063ed3c 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -37,6 +37,7 @@
#include "src/base/platform/platform.h"
#include "src/deoptimizer.h"
#include "src/libplatform/default-platform.h"
+#include "src/log.h"
#include "src/objects-inl.h"
#include "src/profiler/cpu-profiler-inl.h"
#include "src/profiler/profiler-listener.h"
@@ -79,7 +80,7 @@ TEST(StartStop) {
CpuProfilesCollection profiles(isolate);
ProfileGenerator generator(&profiles);
std::unique_ptr<ProfilerEventsProcessor> processor(
- new ProfilerEventsProcessor(isolate, &generator,
+ new SamplingEventsProcessor(isolate, &generator,
v8::base::TimeDelta::FromMicroseconds(100)));
processor->Start();
processor->StopSynchronously();
@@ -89,19 +90,20 @@ static void EnqueueTickSampleEvent(ProfilerEventsProcessor* proc,
i::Address frame1,
i::Address frame2 = kNullAddress,
i::Address frame3 = kNullAddress) {
- v8::TickSample* sample = proc->StartTickSample();
- sample->pc = reinterpret_cast<void*>(frame1);
- sample->tos = reinterpret_cast<void*>(frame1);
- sample->frames_count = 0;
+ v8::internal::TickSample sample;
+ sample.pc = reinterpret_cast<void*>(frame1);
+ sample.tos = reinterpret_cast<void*>(frame1);
+ sample.frames_count = 0;
if (frame2 != kNullAddress) {
- sample->stack[0] = reinterpret_cast<void*>(frame2);
- sample->frames_count = 1;
+ sample.stack[0] = reinterpret_cast<void*>(frame2);
+ sample.frames_count = 1;
}
if (frame3 != kNullAddress) {
- sample->stack[1] = reinterpret_cast<void*>(frame3);
- sample->frames_count = 2;
+ sample.stack[1] = reinterpret_cast<void*>(frame3);
+ sample.frames_count = 2;
}
- proc->FinishTickSample();
+ sample.timestamp = base::TimeTicks::HighResolutionNow();
+ proc->AddSample(sample);
}
namespace {
@@ -123,7 +125,7 @@ class TestSetup {
} // namespace
-i::AbstractCode* CreateCode(LocalContext* env) {
+i::AbstractCode CreateCode(LocalContext* env) {
static int counter = 0;
i::EmbeddedVector<char, 256> script;
i::EmbeddedVector<char, 32> name;
@@ -153,19 +155,17 @@ TEST(CodeEvents) {
i::HandleScope scope(isolate);
- i::AbstractCode* aaa_code = CreateCode(&env);
- i::AbstractCode* comment_code = CreateCode(&env);
- i::AbstractCode* comment2_code = CreateCode(&env);
- i::AbstractCode* moved_code = CreateCode(&env);
+ i::AbstractCode aaa_code = CreateCode(&env);
+ i::AbstractCode comment_code = CreateCode(&env);
+ i::AbstractCode comment2_code = CreateCode(&env);
+ i::AbstractCode moved_code = CreateCode(&env);
CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate);
ProfileGenerator* generator = new ProfileGenerator(profiles);
- ProfilerEventsProcessor* processor = new ProfilerEventsProcessor(
+ ProfilerEventsProcessor* processor = new SamplingEventsProcessor(
isolate, generator, v8::base::TimeDelta::FromMicroseconds(100));
- CpuProfiler profiler(isolate, profiles, generator, processor);
- profiles->StartProfiling("", false);
processor->Start();
- ProfilerListener profiler_listener(isolate, &profiler);
+ ProfilerListener profiler_listener(isolate, processor);
isolate->logger()->AddCodeEventListener(&profiler_listener);
// Enqueue code creation events.
@@ -215,19 +215,19 @@ TEST(TickEvents) {
i::Isolate* isolate = CcTest::i_isolate();
i::HandleScope scope(isolate);
- i::AbstractCode* frame1_code = CreateCode(&env);
- i::AbstractCode* frame2_code = CreateCode(&env);
- i::AbstractCode* frame3_code = CreateCode(&env);
+ i::AbstractCode frame1_code = CreateCode(&env);
+ i::AbstractCode frame2_code = CreateCode(&env);
+ i::AbstractCode frame3_code = CreateCode(&env);
CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate);
ProfileGenerator* generator = new ProfileGenerator(profiles);
ProfilerEventsProcessor* processor =
- new ProfilerEventsProcessor(CcTest::i_isolate(), generator,
+ new SamplingEventsProcessor(CcTest::i_isolate(), generator,
v8::base::TimeDelta::FromMicroseconds(100));
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
- ProfilerListener profiler_listener(isolate, &profiler);
+ ProfilerListener profiler_listener(isolate, processor);
isolate->logger()->AddCodeEventListener(&profiler_listener);
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, frame1_code, "bbb");
@@ -286,28 +286,29 @@ TEST(Issue1398) {
i::Isolate* isolate = CcTest::i_isolate();
i::HandleScope scope(isolate);
- i::AbstractCode* code = CreateCode(&env);
+ i::AbstractCode code = CreateCode(&env);
CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate);
ProfileGenerator* generator = new ProfileGenerator(profiles);
ProfilerEventsProcessor* processor =
- new ProfilerEventsProcessor(CcTest::i_isolate(), generator,
+ new SamplingEventsProcessor(CcTest::i_isolate(), generator,
v8::base::TimeDelta::FromMicroseconds(100));
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
- ProfilerListener profiler_listener(isolate, &profiler);
+ ProfilerListener profiler_listener(isolate, processor);
profiler_listener.CodeCreateEvent(i::Logger::BUILTIN_TAG, code, "bbb");
- v8::TickSample* sample = processor->StartTickSample();
- sample->pc = reinterpret_cast<void*>(code->InstructionStart());
- sample->tos = nullptr;
- sample->frames_count = v8::TickSample::kMaxFramesCount;
- for (unsigned i = 0; i < sample->frames_count; ++i) {
- sample->stack[i] = reinterpret_cast<void*>(code->InstructionStart());
+ v8::internal::TickSample sample;
+ sample.pc = reinterpret_cast<void*>(code->InstructionStart());
+ sample.tos = nullptr;
+ sample.frames_count = v8::TickSample::kMaxFramesCount;
+ for (unsigned i = 0; i < sample.frames_count; ++i) {
+ sample.stack[i] = reinterpret_cast<void*>(code->InstructionStart());
}
- processor->FinishTickSample();
+ sample.timestamp = base::TimeTicks::HighResolutionNow();
+ processor->AddSample(sample);
processor->StopSynchronously();
CpuProfile* profile = profiles->StopProfiling("");
@@ -459,7 +460,9 @@ v8::CpuProfile* ProfilerHelper::Run(v8::Local<v8::Function> function,
v8::internal::CpuProfiler* iprofiler =
reinterpret_cast<v8::internal::CpuProfiler*>(profiler_);
- v8::sampler::Sampler* sampler = iprofiler->processor()->sampler();
+ v8::sampler::Sampler* sampler =
+ reinterpret_cast<i::SamplingEventsProcessor*>(iprofiler->processor())
+ ->sampler();
sampler->StartCountingSamples();
do {
function->Call(context_, context_->Global(), argc, argv).ToLocalChecked();
@@ -1077,7 +1080,7 @@ static const char* bound_function_test_source =
TEST(BoundFunctionCall) {
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
CompileRun(bound_function_test_source);
@@ -1096,7 +1099,9 @@ TEST(BoundFunctionCall) {
// This tests checks distribution of the samples through the source lines.
static void TickLines(bool optimize) {
- if (!optimize) i::FLAG_opt = false;
+#ifndef V8_LITE_MODE
+ FLAG_opt = optimize;
+#endif // V8_LITE_MODE
CcTest::InitializeVM();
LocalContext env;
i::FLAG_allow_natives_syntax = true;
@@ -1132,24 +1137,24 @@ static void TickLines(bool optimize) {
i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*GetFunction(env.local(), func_name)));
- CHECK(func->shared());
- CHECK(func->shared()->abstract_code());
+ CHECK(!func->shared().is_null());
+ CHECK(!func->shared()->abstract_code().is_null());
CHECK(!optimize || func->IsOptimized() ||
!CcTest::i_isolate()->use_optimizer());
- i::AbstractCode* code = func->abstract_code();
- CHECK(code);
+ i::AbstractCode code = func->abstract_code();
+ CHECK(!code.is_null());
i::Address code_address = code->raw_instruction_start();
- CHECK(code_address);
+ CHECK_NE(code_address, kNullAddress);
CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate);
ProfileGenerator* generator = new ProfileGenerator(profiles);
ProfilerEventsProcessor* processor =
- new ProfilerEventsProcessor(CcTest::i_isolate(), generator,
+ new SamplingEventsProcessor(CcTest::i_isolate(), generator,
v8::base::TimeDelta::FromMicroseconds(100));
CpuProfiler profiler(isolate, profiles, generator, processor);
profiles->StartProfiling("", false);
processor->Start();
- ProfilerListener profiler_listener(isolate, &profiler);
+ ProfilerListener profiler_listener(isolate, processor);
// Enqueue code creation events.
i::Handle<i::String> str = factory->NewStringFromAsciiChecked(func_name);
@@ -1340,7 +1345,7 @@ static const char* cpu_profiler_deep_stack_test_source =
// 0 foo 21 #254 no reason
TEST(CpuProfileDeepStack) {
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
ProfilerHelper helper(env);
@@ -1398,7 +1403,7 @@ static void CallJsFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
TEST(JsNativeJsSample) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(
@@ -1451,7 +1456,7 @@ static const char* js_native_js_runtime_js_test_source =
TEST(JsNativeJsRuntimeJsSample) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(
@@ -1508,7 +1513,7 @@ static const char* js_native1_js_native2_js_test_source =
TEST(JsNative1JsNative2JsSample) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
v8::Local<v8::Function> func1 =
@@ -1554,7 +1559,7 @@ static void CallCollectSample(const v8::FunctionCallbackInfo<v8::Value>& info) {
TEST(CollectSampleAPI) {
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
v8::Local<v8::FunctionTemplate> func_template =
@@ -1608,7 +1613,7 @@ static const char* js_native_js_runtime_multiple_test_source =
TEST(JsNativeJsRuntimeJsSampleMultiple) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
v8::Local<v8::FunctionTemplate> func_template =
@@ -1673,7 +1678,7 @@ static const char* inlining_test_source =
TEST(Inlining) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
ProfilerHelper helper(env);
@@ -1697,6 +1702,135 @@ TEST(Inlining) {
profile->Delete();
}
+static const char* inlining_test_source2 = R"(
+ %NeverOptimizeFunction(action);
+ %NeverOptimizeFunction(start);
+ level1();
+ level1();
+ %OptimizeFunctionOnNextCall(level1);
+ %OptimizeFunctionOnNextCall(level2);
+ %OptimizeFunctionOnNextCall(level3);
+ %OptimizeFunctionOnNextCall(level4);
+ level1();
+ function action(n) {
+ var s = 0;
+ for (var i = 0; i < n; ++i) s += i*i*i;
+ return s;
+ }
+ function level4() {
+ action(100);
+ return action(100);
+ }
+ function level3() {
+ const a = level4();
+ const b = level4();
+ return a + b * 1.1;
+ }
+ function level2() {
+ return level3() * 2;
+ }
+ function level1() {
+ action(1);
+ action(200);
+ action(1);
+ return level2();
+ }
+ function start(n) {
+ while (--n)
+ level1();
+ };
+ )";
+
+// The simulator builds are extremely slow. We run them with fewer iterations.
+#ifdef USE_SIMULATOR
+const double load_factor = 0.01;
+#else
+const double load_factor = 1.0;
+#endif
+
+// [Top down]:
+// 0 (root):0 0 #1
+// 13 start:34 6 #3
+// bailed out due to 'Optimization is always disabled'
+// 19 level1:36 6 #4
+// 16 action:29 6 #14
+// bailed out due to 'Optimization is always disabled'
+// 2748 action:30 6 #10
+// bailed out due to 'Optimization is always disabled'
+// 18 action:31 6 #15
+// bailed out due to 'Optimization is always disabled'
+// 0 level2:32 6 #5
+// 0 level3:26 6 #6
+// 12 level4:22 6 #11
+// 1315 action:17 6 #13
+// bailed out due to 'Optimization is always disabled'
+// 1324 action:18 6 #12
+// bailed out due to 'Optimization is always disabled'
+// 16 level4:21 6 #7
+// 1268 action:17 6 #9
+// bailed out due to 'Optimization is always disabled'
+// 1322 action:18 6 #8
+// bailed out due to 'Optimization is always disabled'
+// 2 (program):0 0 #2
+TEST(Inlining2) {
+ FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
+ v8::Context::Scope context_scope(env);
+
+ CompileRun(inlining_test_source2);
+ v8::Local<v8::Function> function = GetFunction(env, "start");
+
+ v8::CpuProfiler* profiler = v8::CpuProfiler::New(CcTest::isolate());
+ v8::Local<v8::String> profile_name = v8_str("inlining");
+ profiler->StartProfiling(profile_name,
+ v8::CpuProfilingMode::kCallerLineNumbers);
+
+ v8::Local<v8::Value> args[] = {
+ v8::Integer::New(env->GetIsolate(), 50000 * load_factor)};
+ function->Call(env, env->Global(), arraysize(args), args).ToLocalChecked();
+ v8::CpuProfile* profile = profiler->StopProfiling(profile_name);
+ CHECK(profile);
+
+ // Dump collected profile to have a better diagnostic in case of failure.
+ reinterpret_cast<i::CpuProfile*>(profile)->Print();
+
+ const v8::CpuProfileNode* root = profile->GetTopDownRoot();
+ const v8::CpuProfileNode* start_node = GetChild(env, root, "start");
+
+ NameLinePair l421_a17[] = {{"level1", 36},
+ {"level2", 32},
+ {"level3", 26},
+ {"level4", 21},
+ {"action", 17}};
+ CheckBranch(start_node, l421_a17, arraysize(l421_a17));
+ NameLinePair l422_a17[] = {{"level1", 36},
+ {"level2", 32},
+ {"level3", 26},
+ {"level4", 22},
+ {"action", 17}};
+ CheckBranch(start_node, l422_a17, arraysize(l422_a17));
+
+ NameLinePair l421_a18[] = {{"level1", 36},
+ {"level2", 32},
+ {"level3", 26},
+ {"level4", 21},
+ {"action", 18}};
+ CheckBranch(start_node, l421_a18, arraysize(l421_a18));
+ NameLinePair l422_a18[] = {{"level1", 36},
+ {"level2", 32},
+ {"level3", 26},
+ {"level4", 22},
+ {"action", 18}};
+ CheckBranch(start_node, l422_a18, arraysize(l422_a18));
+
+ NameLinePair action_direct[] = {{"level1", 36}, {"action", 30}};
+ CheckBranch(start_node, action_direct, arraysize(action_direct));
+
+ profile->Delete();
+ profiler->Dispose();
+}
+
// [Top down]:
// 0 (root) #0 1
// 2 (program) #0 2
@@ -1713,13 +1847,13 @@ TEST(IdleTime) {
i::ProfilerEventsProcessor* processor =
reinterpret_cast<i::CpuProfiler*>(cpu_profiler)->processor();
- processor->AddCurrentStack(isolate, true);
+ processor->AddCurrentStack(true);
isolate->SetIdle(true);
for (int i = 0; i < 3; i++) {
- processor->AddCurrentStack(isolate, true);
+ processor->AddCurrentStack(true);
}
isolate->SetIdle(false);
- processor->AddCurrentStack(isolate, true);
+ processor->AddCurrentStack(true);
v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name);
CHECK(profile);
@@ -1761,7 +1895,7 @@ static void CheckFunctionDetails(v8::Isolate* isolate,
TEST(FunctionDetails) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
ProfilerHelper helper(env);
@@ -1808,7 +1942,7 @@ TEST(FunctionDetailsInlining) {
if (!CcTest::i_isolate()->use_optimizer() || i::FLAG_always_opt) return;
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
ProfilerHelper helper(env);
@@ -1881,12 +2015,12 @@ TEST(FunctionDetailsInlining) {
const v8::CpuProfileNode* beta = FindChild(env, alpha, "beta");
if (!beta) return;
CheckFunctionDetails(env->GetIsolate(), beta, "beta", "script_b",
- script_b->GetUnboundScript()->GetId(), 0, 0);
+ script_b->GetUnboundScript()->GetId(), 1, 14);
}
TEST(DontStopOnFinishedProfileDelete) {
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
v8::CpuProfiler* profiler = v8::CpuProfiler::New(env->GetIsolate());
@@ -1934,7 +2068,7 @@ TEST(CollectDeoptEvents) {
if (!CcTest::i_isolate()->use_optimizer() || i::FLAG_always_opt) return;
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
ProfilerHelper helper(env);
i::CpuProfiler* iprofiler =
@@ -2067,7 +2201,7 @@ TEST(DeoptAtFirstLevelInlinedSource) {
if (!CcTest::i_isolate()->use_optimizer() || i::FLAG_always_opt) return;
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
ProfilerHelper helper(env);
i::CpuProfiler* iprofiler =
@@ -2137,7 +2271,7 @@ TEST(DeoptAtSecondLevelInlinedSource) {
if (!CcTest::i_isolate()->use_optimizer() || i::FLAG_always_opt) return;
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
ProfilerHelper helper(env);
i::CpuProfiler* iprofiler =
@@ -2212,7 +2346,7 @@ TEST(DeoptUntrackedFunction) {
if (!CcTest::i_isolate()->use_optimizer() || i::FLAG_always_opt) return;
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
ProfilerHelper helper(env);
i::CpuProfiler* iprofiler =
@@ -2423,7 +2557,7 @@ TEST(StaticCollectSampleAPI) {
TEST(CodeEntriesMemoryLeak) {
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
std::string source = "function start() {}\n";
@@ -2457,7 +2591,7 @@ TEST(NativeFrameStackTrace) {
// v8::internal::StringTable::LookupStringIfExists_NoAllocate native function
// without producing an EXIT frame.
v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
+ v8::Local<v8::Context> env = CcTest::NewContext({PROFILER_EXTENSION_ID});
v8::Context::Scope context_scope(env);
const char* source = R"(
@@ -2503,6 +2637,7 @@ TEST(SourcePositionTable) {
int no_info = v8::CpuProfileNode::kNoLineNumberInfo;
CHECK_EQ(no_info, info.GetSourceLineNumber(std::numeric_limits<int>::min()));
CHECK_EQ(no_info, info.GetSourceLineNumber(0));
+ CHECK_EQ(SourcePosition::kNotInlined, info.GetInliningId(0));
CHECK_EQ(no_info, info.GetSourceLineNumber(1));
CHECK_EQ(no_info, info.GetSourceLineNumber(9));
CHECK_EQ(no_info, info.GetSourceLineNumber(10));
@@ -2511,12 +2646,14 @@ TEST(SourcePositionTable) {
CHECK_EQ(no_info, info.GetSourceLineNumber(20));
CHECK_EQ(no_info, info.GetSourceLineNumber(21));
CHECK_EQ(no_info, info.GetSourceLineNumber(100));
+ CHECK_EQ(SourcePosition::kNotInlined, info.GetInliningId(100));
CHECK_EQ(no_info, info.GetSourceLineNumber(std::numeric_limits<int>::max()));
- info.SetPosition(10, 1);
- info.SetPosition(20, 2);
+ info.SetPosition(10, 1, SourcePosition::kNotInlined);
+ info.SetPosition(20, 2, SourcePosition::kNotInlined);
- // The only valid return values are 1 or 2 - every pc maps to a line number.
+ // The only valid return values are 1 or 2 - every pc maps to a line
+ // number.
CHECK_EQ(1, info.GetSourceLineNumber(std::numeric_limits<int>::min()));
CHECK_EQ(1, info.GetSourceLineNumber(0));
CHECK_EQ(1, info.GetSourceLineNumber(1));
@@ -2524,16 +2661,22 @@ TEST(SourcePositionTable) {
CHECK_EQ(1, info.GetSourceLineNumber(10));
CHECK_EQ(1, info.GetSourceLineNumber(11));
CHECK_EQ(1, info.GetSourceLineNumber(19));
- CHECK_EQ(2, info.GetSourceLineNumber(20));
+ CHECK_EQ(1, info.GetSourceLineNumber(20));
CHECK_EQ(2, info.GetSourceLineNumber(21));
CHECK_EQ(2, info.GetSourceLineNumber(100));
CHECK_EQ(2, info.GetSourceLineNumber(std::numeric_limits<int>::max()));
+ CHECK_EQ(SourcePosition::kNotInlined, info.GetInliningId(0));
+ CHECK_EQ(SourcePosition::kNotInlined, info.GetInliningId(100));
+
// Test SetPosition behavior.
- info.SetPosition(25, 3);
+ info.SetPosition(25, 3, 0);
CHECK_EQ(2, info.GetSourceLineNumber(21));
CHECK_EQ(3, info.GetSourceLineNumber(100));
CHECK_EQ(3, info.GetSourceLineNumber(std::numeric_limits<int>::max()));
+
+ CHECK_EQ(SourcePosition::kNotInlined, info.GetInliningId(21));
+ CHECK_EQ(0, info.GetInliningId(100));
}
TEST(MultipleProfilers) {
@@ -2545,6 +2688,58 @@ TEST(MultipleProfilers) {
profiler2->StopProfiling("2");
}
+void ProfileSomeCode(v8::Isolate* isolate) {
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::HandleScope scope(isolate);
+ LocalContext context(isolate);
+
+ v8::CpuProfiler* profiler = v8::CpuProfiler::New(isolate);
+
+ v8::Local<v8::String> profile_name = v8_str("1");
+ profiler->StartProfiling(profile_name);
+ const char* source = R"(
+ function foo() {
+ var x = 0;
+ for (var i = 0; i < 1e3; i++) {
+ for (var j = 0; j < 1e3; j++) {
+ x = i * j;
+ }
+ }
+ return x;
+ }
+ foo();
+ )";
+
+ CompileRun(source);
+ profiler->StopProfiling(profile_name);
+ profiler->Dispose();
+}
+
+class IsolateThread : public v8::base::Thread {
+ public:
+ IsolateThread() : Thread(Options("IsolateThread")) {}
+
+ void Run() override {
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+ ProfileSomeCode(isolate);
+ isolate->Dispose();
+ }
+};
+
+// Checking for crashes and TSAN issues with multiple isolates profiling.
+TEST(MultipleIsolates) {
+ IsolateThread thread1;
+ IsolateThread thread2;
+
+ thread1.Start();
+ thread2.Start();
+
+ thread1.Join();
+ thread2.Join();
+}
+
int GetSourcePositionEntryCount(i::Isolate* isolate, const char* source) {
i::Handle<i::JSFunction> function = i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*CompileRun(source)));