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

Side by Side Diff: runtime/vm/pages.cc

Issue 11734028: - Consolidate verbose-gc output to be a single line which can be imported easily into spreadsheets. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/pages.h" 5 #include "vm/pages.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/compiler_stats.h" 8 #include "vm/compiler_stats.h"
9 #include "vm/gc_marker.h" 9 #include "vm/gc_marker.h"
10 #include "vm/gc_sweeper.h" 10 #include "vm/gc_sweeper.h"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 111
112 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity) 112 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity)
113 : freelist_(), 113 : freelist_(),
114 heap_(heap), 114 heap_(heap),
115 pages_(NULL), 115 pages_(NULL),
116 pages_tail_(NULL), 116 pages_tail_(NULL),
117 large_pages_(NULL), 117 large_pages_(NULL),
118 max_capacity_(max_capacity), 118 max_capacity_(max_capacity),
119 capacity_(0), 119 capacity_(0),
120 in_use_(0), 120 in_use_(0),
121 count_(0),
122 sweeping_(false), 121 sweeping_(false),
123 page_space_controller_(FLAG_heap_growth_space_ratio, 122 page_space_controller_(FLAG_heap_growth_space_ratio,
124 FLAG_heap_growth_rate, 123 FLAG_heap_growth_rate,
125 FLAG_heap_growth_time_ratio) { 124 FLAG_heap_growth_time_ratio) {
126 } 125 }
127 126
128 127
129 PageSpace::~PageSpace() { 128 PageSpace::~PageSpace() {
130 FreePages(pages_); 129 FreePages(pages_);
131 FreePages(large_pages_); 130 FreePages(large_pages_);
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 page = page->next(); 394 page = page->next();
396 } 395 }
397 page = large_pages_; 396 page = large_pages_;
398 while (page != NULL) { 397 while (page != NULL) {
399 page->WriteProtect(read_only); 398 page->WriteProtect(read_only);
400 page = page->next(); 399 page = page->next();
401 } 400 }
402 } 401 }
403 402
404 403
405 void PageSpace::MarkSweep(bool invoke_api_callbacks, const char* gc_reason) { 404 void PageSpace::MarkSweep(bool invoke_api_callbacks) {
406 // MarkSweep is not reentrant. Make sure that is the case. 405 // MarkSweep is not reentrant. Make sure that is the case.
407 ASSERT(!sweeping_); 406 ASSERT(!sweeping_);
408 sweeping_ = true; 407 sweeping_ = true;
409 Isolate* isolate = Isolate::Current(); 408 Isolate* isolate = Isolate::Current();
410 NoHandleScope no_handles(isolate); 409 NoHandleScope no_handles(isolate);
411 410
412 if (HeapTrace::is_enabled()) { 411 if (HeapTrace::is_enabled()) {
413 isolate->heap()->trace()->TraceMarkSweepStart(); 412 isolate->heap()->trace()->TraceMarkSweepStart();
414 } 413 }
415 414
416 if (FLAG_print_free_list_before_gc) { 415 if (FLAG_print_free_list_before_gc) {
417 OS::Print("Data Freelist (before GC):\n"); 416 OS::Print("Data Freelist (before GC):\n");
418 freelist_[HeapPage::kData].Print(); 417 freelist_[HeapPage::kData].Print();
419 OS::Print("Executable Freelist (before GC):\n"); 418 OS::Print("Executable Freelist (before GC):\n");
420 freelist_[HeapPage::kExecutable].Print(); 419 freelist_[HeapPage::kExecutable].Print();
421 } 420 }
422 421
423 if (FLAG_verify_before_gc) { 422 if (FLAG_verify_before_gc) {
424 OS::PrintErr("Verifying before MarkSweep..."); 423 OS::PrintErr("Verifying before MarkSweep...");
425 heap_->Verify(); 424 heap_->Verify();
426 OS::PrintErr(" done.\n"); 425 OS::PrintErr(" done.\n");
427 } 426 }
428 427
429 if (FLAG_verbose_gc) { 428 int64_t start = OS::GetCurrentTimeMicros();
430 OS::PrintErr("Start mark sweep for %s collection\n", gc_reason);
431 }
432 Timer timer(true, "MarkSweep");
433 timer.Start();
434 int64_t start = OS::GetCurrentTimeMillis();
435 429
436 // Mark all reachable old-gen objects. 430 // Mark all reachable old-gen objects.
437 GCMarker marker(heap_); 431 GCMarker marker(heap_);
438 marker.MarkObjects(isolate, this, invoke_api_callbacks); 432 marker.MarkObjects(isolate, this, invoke_api_callbacks);
439 433
434 int64_t mid1 = OS::GetCurrentTimeMicros();
435
440 // Reset the bump allocation page to unused. 436 // Reset the bump allocation page to unused.
441 // Reset the freelists and setup sweeping. 437 // Reset the freelists and setup sweeping.
442 freelist_[HeapPage::kData].Reset(); 438 freelist_[HeapPage::kData].Reset();
443 freelist_[HeapPage::kExecutable].Reset(); 439 freelist_[HeapPage::kExecutable].Reset();
440
441 int64_t mid2 = OS::GetCurrentTimeMicros();
442
444 GCSweeper sweeper(heap_); 443 GCSweeper sweeper(heap_);
445 intptr_t in_use = 0; 444 intptr_t in_use = 0;
446 445
447 HeapPage* prev_page = NULL; 446 HeapPage* prev_page = NULL;
448 HeapPage* page = pages_; 447 HeapPage* page = pages_;
449 while (page != NULL) { 448 while (page != NULL) {
450 HeapPage* next_page = page->next(); 449 HeapPage* next_page = page->next();
451 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]); 450 intptr_t page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]);
452 if (page_in_use == 0) { 451 if (page_in_use == 0) {
453 FreePage(page, prev_page); 452 FreePage(page, prev_page);
454 } else { 453 } else {
455 in_use += page_in_use; 454 in_use += page_in_use;
456 prev_page = page; 455 prev_page = page;
457 } 456 }
458 // Advance to the next page. 457 // Advance to the next page.
459 page = next_page; 458 page = next_page;
460 } 459 }
461 460
461 int64_t mid3 = OS::GetCurrentTimeMicros();
462
462 prev_page = NULL; 463 prev_page = NULL;
463 page = large_pages_; 464 page = large_pages_;
464 while (page != NULL) { 465 while (page != NULL) {
465 intptr_t page_in_use = sweeper.SweepLargePage(page); 466 intptr_t page_in_use = sweeper.SweepLargePage(page);
466 HeapPage* next_page = page->next(); 467 HeapPage* next_page = page->next();
467 if (page_in_use == 0) { 468 if (page_in_use == 0) {
468 FreeLargePage(page, prev_page); 469 FreeLargePage(page, prev_page);
469 } else { 470 } else {
470 in_use += page_in_use; 471 in_use += page_in_use;
471 prev_page = page; 472 prev_page = page;
472 } 473 }
473 // Advance to the next page. 474 // Advance to the next page.
474 page = next_page; 475 page = next_page;
475 } 476 }
476 477
477 // Record data and print if requested. 478 // Record data and print if requested.
478 intptr_t in_use_before = in_use_; 479 intptr_t in_use_before = in_use_;
479 in_use_ = in_use; 480 in_use_ = in_use;
480 481
481 int64_t end = OS::GetCurrentTimeMillis(); 482 int64_t end = OS::GetCurrentTimeMicros();
482 timer.Stop();
483 483
484 // Record signals for growth control. 484 // Record signals for growth control.
485 page_space_controller_.EvaluateGarbageCollection(in_use_before, in_use, 485 page_space_controller_.EvaluateGarbageCollection(in_use_before, in_use,
486 start, end); 486 start, end);
487 487
488 if (FLAG_verbose_gc) { 488 heap_->RecordTime(0, mid1 - start);
489 const intptr_t KB2 = KB / 2; 489 heap_->RecordTime(1, mid2 - mid1);
490 OS::PrintErr("Mark-Sweep[%d]: %"Pd64"us (%"Pd"K -> %"Pd"K, %"Pd"K)\n", 490 heap_->RecordTime(2, mid3 - mid2);
491 count_, 491 heap_->RecordTime(3, end - mid3);
492 timer.TotalElapsedTime(),
493 (in_use_before + (KB2)) / KB,
494 (in_use + (KB2)) / KB,
495 (capacity_ + KB2) / KB);
496 }
497 492
498 if (FLAG_print_free_list_after_gc) { 493 if (FLAG_print_free_list_after_gc) {
499 OS::Print("Data Freelist (after GC):\n"); 494 OS::Print("Data Freelist (after GC):\n");
500 freelist_[HeapPage::kData].Print(); 495 freelist_[HeapPage::kData].Print();
501 OS::Print("Executable Freelist (after GC):\n"); 496 OS::Print("Executable Freelist (after GC):\n");
502 freelist_[HeapPage::kExecutable].Print(); 497 freelist_[HeapPage::kExecutable].Print();
503 } 498 }
504 499
505 if (FLAG_verify_after_gc) { 500 if (FLAG_verify_after_gc) {
506 OS::PrintErr("Verifying after MarkSweep..."); 501 OS::PrintErr("Verifying after MarkSweep...");
507 heap_->Verify(); 502 heap_->Verify();
508 OS::PrintErr(" done.\n"); 503 OS::PrintErr(" done.\n");
509 } 504 }
510 505
511 if (HeapTrace::is_enabled()) { 506 if (HeapTrace::is_enabled()) {
512 isolate->heap()->trace()->TraceMarkSweepFinish(); 507 isolate->heap()->trace()->TraceMarkSweepFinish();
513 } 508 }
514 509
515 count_++;
516 // Done, reset the marker. 510 // Done, reset the marker.
517 ASSERT(sweeping_); 511 ASSERT(sweeping_);
518 sweeping_ = false; 512 sweeping_ = false;
519 } 513 }
520 514
521 515
522 PageSpaceController::PageSpaceController(int heap_growth_ratio, 516 PageSpaceController::PageSpaceController(int heap_growth_ratio,
523 int heap_growth_rate, 517 int heap_growth_rate,
524 int garbage_collection_time_ratio) 518 int garbage_collection_time_ratio)
525 : is_enabled_(false), 519 : is_enabled_(false),
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 int collected_garbage_ratio = 553 int collected_garbage_ratio =
560 static_cast<int>((static_cast<double>(in_use_before - in_use_after) / 554 static_cast<int>((static_cast<double>(in_use_before - in_use_after) /
561 static_cast<double>(in_use_before)) 555 static_cast<double>(in_use_before))
562 * 100.0); 556 * 100.0);
563 bool enough_free_space = 557 bool enough_free_space =
564 (collected_garbage_ratio >= heap_growth_ratio_); 558 (collected_garbage_ratio >= heap_growth_ratio_);
565 int garbage_collection_time_fraction = 559 int garbage_collection_time_fraction =
566 history_.GarbageCollectionTimeFraction(); 560 history_.GarbageCollectionTimeFraction();
567 bool enough_free_time = 561 bool enough_free_time =
568 (garbage_collection_time_fraction <= garbage_collection_time_ratio_); 562 (garbage_collection_time_fraction <= garbage_collection_time_ratio_);
563
564 Heap* heap = Isolate::Current()->heap();
569 if (enough_free_space && enough_free_time) { 565 if (enough_free_space && enough_free_time) {
570 grow_heap_ = 0; 566 grow_heap_ = 0;
571 } else { 567 } else {
572 if (FLAG_verbose_gc) {
573 OS::PrintErr("PageSpaceController: ");
574 if (!enough_free_space) {
575 OS::PrintErr("free space %d%% < %d%%",
576 collected_garbage_ratio,
577 heap_growth_ratio_);
578 }
579 if (!enough_free_space && !enough_free_time) {
580 OS::PrintErr(", ");
581 }
582 if (!enough_free_time) {
583 OS::PrintErr("garbage collection time %d%% > %d%%",
584 garbage_collection_time_fraction,
585 garbage_collection_time_ratio_);
586 }
587 OS::PrintErr("\n");
588 }
589 intptr_t growth_target = static_cast<intptr_t>(in_use_after / 568 intptr_t growth_target = static_cast<intptr_t>(in_use_after /
590 desired_utilization_); 569 desired_utilization_);
591 intptr_t growth_in_bytes = Utils::RoundUp(growth_target - in_use_after, 570 intptr_t growth_in_bytes = Utils::RoundUp(growth_target - in_use_after,
592 PageSpace::kPageSize); 571 PageSpace::kPageSize);
593 int growth_in_pages = growth_in_bytes / PageSpace::kPageSize; 572 int growth_in_pages = growth_in_bytes / PageSpace::kPageSize;
594 grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_); 573 grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_);
574 heap->RecordData(2, growth_in_pages);
595 } 575 }
576 heap->RecordData(0, collected_garbage_ratio);
577 heap->RecordData(1, garbage_collection_time_fraction);
578 heap->RecordData(3, grow_heap_);
596 } 579 }
597 580
598 581
599 PageSpaceGarbageCollectionHistory::PageSpaceGarbageCollectionHistory() 582 PageSpaceGarbageCollectionHistory::PageSpaceGarbageCollectionHistory()
600 : index_(0) { 583 : index_(0) {
601 for (intptr_t i = 0; i < kHistoryLength; i++) { 584 for (intptr_t i = 0; i < kHistoryLength; i++) {
602 start_[i] = 0; 585 start_[i] = 0;
603 end_[i] = 0; 586 end_[i] = 0;
604 } 587 }
605 } 588 }
(...skipping 27 matching lines...) Expand all
633 return 0; 616 return 0;
634 } else { 617 } else {
635 ASSERT(total_time >= gc_time); 618 ASSERT(total_time >= gc_time);
636 int result= static_cast<int>((static_cast<double>(gc_time) / 619 int result= static_cast<int>((static_cast<double>(gc_time) /
637 static_cast<double>(total_time)) * 100); 620 static_cast<double>(total_time)) * 100);
638 return result; 621 return result;
639 } 622 }
640 } 623 }
641 624
642 } // namespace dart 625 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698