Commit 487a6193 authored by loislo@chromium.org's avatar loislo@chromium.org

Improve test-cpu-profiler.cc tests stability

The tests sometimes fail on bots as they don't have time to collect enough samples. This change makes them use counter of samples taken when v8 is either in JS or EXTERNAL state and repeat sampling until desired threshold is reached.

BUG=v8:2628
R=loislo@chromium.org, yangguo@chromium.org

Review URL: https://codereview.chromium.org/18418004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15592 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent daacd583
......@@ -658,7 +658,8 @@ Sampler::Sampler(Isolate* isolate, int interval)
interval_(interval),
profiling_(false),
active_(false),
samples_taken_(0) {
is_counting_samples_(false),
js_and_external_sample_count_(0) {
data_ = new PlatformData;
}
......@@ -688,7 +689,11 @@ void Sampler::SampleStack(const RegisterState& state) {
TickSample sample_obj;
if (sample == NULL) sample = &sample_obj;
sample->Init(isolate_, state);
if (++samples_taken_ < 0) samples_taken_ = 0;
if (is_counting_samples_) {
if (sample->state == JS || sample->state == EXTERNAL) {
++js_and_external_sample_count_;
}
}
Tick(sample);
}
......
......@@ -103,8 +103,13 @@ class Sampler {
bool IsActive() const { return NoBarrier_Load(&active_); }
// Used in tests to make sure that stack sampling is performed.
int samples_taken() const { return samples_taken_; }
void ResetSamplesTaken() { samples_taken_ = 0; }
unsigned js_and_external_sample_count() const {
return js_and_external_sample_count_;
}
void StartCountingSamples() {
is_counting_samples_ = true;
js_and_external_sample_count_ = 0;
}
class PlatformData;
PlatformData* platform_data() const { return data_; }
......@@ -122,7 +127,9 @@ class Sampler {
Atomic32 profiling_;
Atomic32 active_;
PlatformData* data_; // Platform specific data.
int samples_taken_; // Counts stack samples taken.
bool is_counting_samples_;
// Counts stack samples taken in JS VM state.
unsigned js_and_external_sample_count_;
DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
};
......
......@@ -413,6 +413,33 @@ TEST(GetProfilerWhenIsolateIsNotInitialized) {
}
static const v8::CpuProfile* RunProfiler(
LocalContext& env, v8::Handle<v8::Function> function,
v8::Handle<v8::Value> argv[], int argc,
unsigned min_js_samples) {
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
i::Sampler* sampler =
reinterpret_cast<i::Isolate*>(env->GetIsolate())->logger()->sampler();
sampler->StartCountingSamples();
do {
function->Call(env->Global(), argc, argv);
} while (sampler->js_and_external_sample_count() < min_js_samples);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
return profile;
}
static bool ContainsString(v8::Handle<v8::String> string,
const Vector<v8::Handle<v8::String> >& vector) {
for (int i = 0; i < vector.length(); i++) {
......@@ -526,24 +553,11 @@ TEST(CollectCpuProfile) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::New("start")));
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
int32_t profiling_interval_ms = 200;
#if defined(_WIN32) || defined(_WIN64)
// 200ms is not enough on Windows. See
// https://code.google.com/p/v8/issues/detail?id=2628
profiling_interval_ms = 500;
#endif
v8::Handle<v8::Value> args[] = { v8::Integer::New(profiling_interval_ms) };
const v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 200);
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
......@@ -566,6 +580,7 @@ TEST(CollectCpuProfile) {
const char* delayBranch[] = { "delay", "loop" };
CheckSimpleBranch(fooNode, delayBranch, ARRAY_SIZE(delayBranch));
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
cpu_profiler->DeleteAllCpuProfiles();
}
......@@ -599,23 +614,14 @@ TEST(SampleWhenFrameIsNotSetup) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::New("start")));
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
int32_t repeat_count = 100;
#if defined(USE_SIMULATOR)
// Simulators are much slower.
repeat_count = 1;
#endif
v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) };
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
const v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
......@@ -637,6 +643,7 @@ TEST(SampleWhenFrameIsNotSetup) {
}
}
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
cpu_profiler->DeleteAllCpuProfiles();
}
......@@ -729,25 +736,17 @@ TEST(NativeAccessorUninitializedIC) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::New("start")));
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
int32_t repeat_count = 1;
v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) };
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
const v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 180);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
const v8::CpuProfileNode* startNode = GetChild(root, "start");
GetChild(startNode, "get foo");
GetChild(startNode, "set foo");
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
cpu_profiler->DeleteAllCpuProfiles();
}
......@@ -787,25 +786,17 @@ TEST(NativeAccessorMonomorphicIC) {
accessors.set_warming_up(false);
}
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
int32_t repeat_count = 100;
v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) };
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
const v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 200);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
const v8::CpuProfileNode* startNode = GetChild(root, "start");
GetChild(startNode, "get foo");
GetChild(startNode, "set foo");
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
cpu_profiler->DeleteAllCpuProfiles();
}
......@@ -840,24 +831,16 @@ TEST(NativeMethodUninitializedIC) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::New("start")));
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
int32_t repeat_count = 1;
v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) };
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
const v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
const v8::CpuProfileNode* startNode = GetChild(root, "start");
GetChild(startNode, "fooMethod");
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
cpu_profiler->DeleteAllCpuProfiles();
}
......@@ -894,25 +877,17 @@ TEST(NativeMethodMonomorphicIC) {
callbacks.set_warming_up(false);
}
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
int32_t repeat_count = 100;
v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) };
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
const v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
GetChild(root, "start");
const v8::CpuProfileNode* startNode = GetChild(root, "start");
GetChild(startNode, "fooMethod");
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
cpu_profiler->DeleteAllCpuProfiles();
}
......@@ -939,19 +914,10 @@ TEST(BoundFunctionCall) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::New("start")));
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
int32_t duration_ms = 100;
v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) };
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
const v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
ScopedVector<v8::Handle<v8::String> > names(3);
......@@ -964,6 +930,7 @@ TEST(BoundFunctionCall) {
const v8::CpuProfileNode* startNode = GetChild(root, "start");
GetChild(startNode, "foo");
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
cpu_profiler->DeleteAllCpuProfiles();
}
......@@ -1003,24 +970,10 @@ TEST(FunctionCallSample) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::New("start")));
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
int32_t duration_ms = 100;
#if defined(_WIN32) || defined(_WIN64)
// 100ms is not enough on Windows. See
// https://code.google.com/p/v8/issues/detail?id=2628
duration_ms = 400;
#endif
v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) };
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
const v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
{
......@@ -1054,6 +1007,7 @@ TEST(FunctionCallSample) {
CheckChildrenNames(unresolvedNode, names);
}
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
cpu_profiler->DeleteAllCpuProfiles();
}
......@@ -1091,24 +1045,11 @@ TEST(FunctionApplySample) {
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::New("start")));
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
v8::Local<v8::String> profile_name = v8::String::New("my_profile");
cpu_profiler->StartCpuProfiling(profile_name);
int32_t duration_ms = 100;
#if defined(_WIN32) || defined(_WIN64)
// 100ms is not enough on Windows. See
// https://code.google.com/p/v8/issues/detail?id=2628
duration_ms = 400;
#endif
v8::Handle<v8::Value> args[] = { v8::Integer::New(duration_ms) };
function->Call(env->Global(), ARRAY_SIZE(args), args);
const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
reinterpret_cast<i::CpuProfile*>(
const_cast<v8::CpuProfile*>(profile))->Print();
const v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
{
......@@ -1146,5 +1087,6 @@ TEST(FunctionApplySample) {
}
}
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
cpu_profiler->DeleteAllCpuProfiles();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment