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

Side by Side Diff: test/cctest/test-cpu-profiler.cc

Issue 13627002: Add sanity test for CPU profiler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Start sampler and processor threads synchronously Created 7 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/profile-generator.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 12 matching lines...) Expand all
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 // 27 //
28 // Tests of profiles generator and utilities. 28 // Tests of profiles generator and utilities.
29 29
30 #include "v8.h" 30 #include "v8.h"
31 #include "cpu-profiler-inl.h" 31 #include "cpu-profiler-inl.h"
32 #include "cctest.h" 32 #include "cctest.h"
33 #include "utils.h"
33 #include "../include/v8-profiler.h" 34 #include "../include/v8-profiler.h"
34 35
35 using i::CodeEntry; 36 using i::CodeEntry;
36 using i::CpuProfile; 37 using i::CpuProfile;
37 using i::CpuProfiler; 38 using i::CpuProfiler;
38 using i::CpuProfilesCollection; 39 using i::CpuProfilesCollection;
39 using i::ProfileGenerator; 40 using i::ProfileGenerator;
40 using i::ProfileNode; 41 using i::ProfileNode;
41 using i::ProfilerEventsProcessor; 42 using i::ProfilerEventsProcessor;
43 using i::ScopedVector;
42 using i::TokenEnumerator; 44 using i::TokenEnumerator;
45 using i::Vector;
43 46
44 47
45 TEST(StartStop) { 48 TEST(StartStop) {
46 CpuProfilesCollection profiles; 49 CpuProfilesCollection profiles;
47 ProfileGenerator generator(&profiles); 50 ProfileGenerator generator(&profiles);
48 ProfilerEventsProcessor processor(&generator); 51 ProfilerEventsProcessor processor(&generator);
49 processor.Start(); 52 processor.Start();
50 processor.Stop(); 53 processor.Stop();
51 processor.Join(); 54 processor.Join();
52 } 55 }
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 CHECK_EQ(NULL, cpu_profiler->FindCpuProfile(uid2)); 395 CHECK_EQ(NULL, cpu_profiler->FindCpuProfile(uid2));
393 CHECK_EQ(p3, cpu_profiler->FindCpuProfile(uid3)); 396 CHECK_EQ(p3, cpu_profiler->FindCpuProfile(uid3));
394 const_cast<v8::CpuProfile*>(p2)->Delete(); 397 const_cast<v8::CpuProfile*>(p2)->Delete();
395 CHECK_EQ(1, cpu_profiler->GetProfileCount()); 398 CHECK_EQ(1, cpu_profiler->GetProfileCount());
396 CHECK_EQ(NULL, cpu_profiler->FindCpuProfile(uid2)); 399 CHECK_EQ(NULL, cpu_profiler->FindCpuProfile(uid2));
397 CHECK_EQ(p3, cpu_profiler->FindCpuProfile(uid3)); 400 CHECK_EQ(p3, cpu_profiler->FindCpuProfile(uid3));
398 const_cast<v8::CpuProfile*>(p3)->Delete(); 401 const_cast<v8::CpuProfile*>(p3)->Delete();
399 CHECK_EQ(0, cpu_profiler->GetProfileCount()); 402 CHECK_EQ(0, cpu_profiler->GetProfileCount());
400 CHECK_EQ(NULL, cpu_profiler->FindCpuProfile(uid3)); 403 CHECK_EQ(NULL, cpu_profiler->FindCpuProfile(uid3));
401 } 404 }
405
406
407 static bool ContainsString(v8::Handle<v8::String> string,
408 const Vector<v8::Handle<v8::String> >& vector) {
409 for (int i = 0; i < vector.length(); i++) {
410 if (string->Equals(vector[i]))
411 return true;
412 }
413 return false;
414 }
415
416
417 static void CheckChildrenNames(const v8::CpuProfileNode* node,
418 const Vector<v8::Handle<v8::String> >& names) {
419 int count = node->GetChildrenCount();
420 for (int i = 0; i < count; i++) {
421 v8::Handle<v8::String> name = node->GetChild(i)->GetFunctionName();
422 CHECK(ContainsString(name, names));
423 // Check that there are no duplicates.
424 for (int j = 0; j < count; j++) {
425 if (j == i) continue;
426 CHECK_NE(name, node->GetChild(j)->GetFunctionName());
427 }
428 }
429 }
430
431
432 static const v8::CpuProfileNode* FindChild(const v8::CpuProfileNode* node,
433 const char* name) {
434 int count = node->GetChildrenCount();
435 v8::Handle<v8::String> nameHandle = v8::String::New(name);
436 for (int i = 0; i < count; i++) {
437 const v8::CpuProfileNode* child = node->GetChild(i);
438 if (nameHandle->Equals(child->GetFunctionName())) return child;
439 }
440 CHECK(false);
441 return NULL;
442 }
443
444
445 static void CheckSimpleBranch(const v8::CpuProfileNode* node,
446 const char* names[], int length) {
447 for (int i = 0; i < length; i++) {
448 const char* name = names[i];
449 node = FindChild(node, name);
450 CHECK(node);
451 int expectedChildrenCount = (i == length - 1) ? 0 : 1;
452 CHECK_EQ(expectedChildrenCount, node->GetChildrenCount());
453 }
454 }
455
456
457 static const char* cpu_profiler_test_source = "function loop(timeout) {\n"
458 " this.mmm = 0;\n"
459 " var start = Date.now();\n"
460 " while (Date.now() - start < timeout) {\n"
461 " var n = 100*1000;\n"
462 " while(n > 1) {\n"
463 " n--;\n"
464 " this.mmm += n * n * n;\n"
465 " }\n"
466 " }\n"
467 "}\n"
468 "function delay() { try { loop(10); } catch(e) { } }\n"
469 "function bar() { delay(); }\n"
470 "function baz() { delay(); }\n"
471 "function foo() {\n"
472 " try {\n"
473 " delay();\n"
474 " bar();\n"
475 " delay();\n"
476 " baz();\n"
477 " } catch (e) { }\n"
478 "}\n"
479 "function start() {\n"
480 " var start = Date.now();\n"
481 " do {\n"
482 " foo();\n"
483 " var duration = Date.now() - start;\n"
484 " } while (duration < 200);\n"
485 " return duration;\n"
486 "}\n";
487
488
489 // Check that the profile tree for the script above will look like the
490 // following:
491 //
492 // [Top down]:
493 // 1062 0 (root) [-1]
494 // 1054 0 start [-1]
495 // 1054 1 foo [-1]
496 // 265 0 baz [-1]
497 // 265 1 delay [-1]
498 // 264 264 loop [-1]
499 // 525 3 delay [-1]
500 // 522 522 loop [-1]
501 // 263 0 bar [-1]
502 // 263 1 delay [-1]
503 // 262 262 loop [-1]
504 // 2 2 (program) [-1]
505 // 6 6 (garbage collector) [-1]
506 TEST(CollectCpuProfile) {
507 LocalContext env;
508 v8::HandleScope scope(env->GetIsolate());
509
510 v8::Script::Compile(v8::String::New(cpu_profiler_test_source))->Run();
511 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
512 env->Global()->Get(v8::String::New("start")));
513
514 v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
515 v8::Local<v8::String> profile_name = v8::String::New("my_profile");
516
517 cpu_profiler->StartCpuProfiling(profile_name);
518 function->Call(env->Global(), 0, 0);
519 const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
520
521 CHECK_NE(NULL, profile);
522 // Dump collected profile to have a better diagnostic in case of failure.
523 reinterpret_cast<i::CpuProfile*>(
524 const_cast<v8::CpuProfile*>(profile))->Print();
525
526 const v8::CpuProfileNode* root = profile->GetTopDownRoot();
527
528 ScopedVector<v8::Handle<v8::String> > names(3);
529 names[0] = v8::String::New(ProfileGenerator::kGarbageCollectorEntryName);
530 names[1] = v8::String::New(ProfileGenerator::kProgramEntryName);
531 names[2] = v8::String::New("start");
532 CheckChildrenNames(root, names);
533
534 const v8::CpuProfileNode* startNode = FindChild(root, "start");
535 CHECK_EQ(1, startNode->GetChildrenCount());
536
537 const v8::CpuProfileNode* fooNode = FindChild(startNode, "foo");
538 CHECK_EQ(3, fooNode->GetChildrenCount());
539
540 const char* barBranch[] = { "bar", "delay", "loop" };
541 CheckSimpleBranch(fooNode, barBranch, ARRAY_SIZE(barBranch));
542 const char* bazBranch[] = { "baz", "delay", "loop" };
543 CheckSimpleBranch(fooNode, bazBranch, ARRAY_SIZE(bazBranch));
544 const char* delayBranch[] = { "delay", "loop" };
545 CheckSimpleBranch(fooNode, delayBranch, ARRAY_SIZE(delayBranch));
546 }
OLDNEW
« no previous file with comments | « src/profile-generator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698