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
This commit is contained in:
parent
daacd5830e
commit
487a61934f
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user