| OLD | NEW |
| 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/heap.h" | 5 #include "vm/heap.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/heap_histogram.h" | 10 #include "vm/heap_histogram.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 "e.g: --old_gen_heap_size=1024 allocates a 1024MB old gen heap"); | 37 "e.g: --old_gen_heap_size=1024 allocates a 1024MB old gen heap"); |
| 38 | 38 |
| 39 Heap::Heap() : read_only_(false), gc_in_progress_(false) { | 39 Heap::Heap() : read_only_(false), gc_in_progress_(false) { |
| 40 for (int sel = 0; | 40 for (int sel = 0; |
| 41 sel < kNumWeakSelectors; | 41 sel < kNumWeakSelectors; |
| 42 sel++) { | 42 sel++) { |
| 43 new_weak_tables_[sel] = new WeakTable(); | 43 new_weak_tables_[sel] = new WeakTable(); |
| 44 old_weak_tables_[sel] = new WeakTable(); | 44 old_weak_tables_[sel] = new WeakTable(); |
| 45 } | 45 } |
| 46 new_space_ = new Scavenger(this, | 46 new_space_ = new Scavenger(this, |
| 47 (FLAG_new_gen_heap_size * MB), | 47 (FLAG_new_gen_heap_size * MBInWords), |
| 48 kNewObjectAlignmentOffset); | 48 kNewObjectAlignmentOffset); |
| 49 old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MB)); | 49 old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MBInWords)); |
| 50 stats_.num_ = 0; | 50 stats_.num_ = 0; |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| 54 Heap::~Heap() { | 54 Heap::~Heap() { |
| 55 delete new_space_; | 55 delete new_space_; |
| 56 delete old_space_; | 56 delete old_space_; |
| 57 for (int sel = 0; | 57 for (int sel = 0; |
| 58 sel < kNumWeakSelectors; | 58 sel < kNumWeakSelectors; |
| 59 sel++) { | 59 sel++) { |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 244 |
| 245 | 245 |
| 246 void Heap::Init(Isolate* isolate) { | 246 void Heap::Init(Isolate* isolate) { |
| 247 ASSERT(isolate->heap() == NULL); | 247 ASSERT(isolate->heap() == NULL); |
| 248 Heap* heap = new Heap(); | 248 Heap* heap = new Heap(); |
| 249 isolate->set_heap(heap); | 249 isolate->set_heap(heap); |
| 250 } | 250 } |
| 251 | 251 |
| 252 | 252 |
| 253 void Heap::StartEndAddress(uword* start, uword* end) const { | 253 void Heap::StartEndAddress(uword* start, uword* end) const { |
| 254 ASSERT(new_space_->capacity() != 0); | 254 ASSERT(new_space_->CapacityInWords() != 0); |
| 255 new_space_->StartEndAddress(start, end); | 255 new_space_->StartEndAddress(start, end); |
| 256 if (old_space_->capacity() != 0) { | 256 if (old_space_->CapacityInWords() != 0) { |
| 257 uword old_start; | 257 uword old_start; |
| 258 uword old_end; | 258 uword old_end; |
| 259 old_space_->StartEndAddress(&old_start, &old_end); | 259 old_space_->StartEndAddress(&old_start, &old_end); |
| 260 *start = Utils::Minimum(old_start, *start); | 260 *start = Utils::Minimum(old_start, *start); |
| 261 *end = Utils::Maximum(old_end, *end); | 261 *end = Utils::Maximum(old_end, *end); |
| 262 } | 262 } |
| 263 ASSERT(*start <= *end); | 263 ASSERT(*start <= *end); |
| 264 } | 264 } |
| 265 | 265 |
| 266 | 266 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 291 isolate->heap()->IteratePointers(&visitor); | 291 isolate->heap()->IteratePointers(&visitor); |
| 292 delete allocated_set; | 292 delete allocated_set; |
| 293 // Only returning a value so that Heap::Validate can be called from an ASSERT. | 293 // Only returning a value so that Heap::Validate can be called from an ASSERT. |
| 294 return true; | 294 return true; |
| 295 } | 295 } |
| 296 | 296 |
| 297 | 297 |
| 298 void Heap::PrintSizes() const { | 298 void Heap::PrintSizes() const { |
| 299 OS::PrintErr("New space (%" Pd "k of %" Pd "k) " | 299 OS::PrintErr("New space (%" Pd "k of %" Pd "k) " |
| 300 "Old space (%" Pd "k of %" Pd "k)\n", | 300 "Old space (%" Pd "k of %" Pd "k)\n", |
| 301 (Used(kNew) / KB), (Capacity(kNew) / KB), | 301 (UsedInWords(kNew) / KBInWords), |
| 302 (Used(kOld) / KB), (Capacity(kOld) / KB)); | 302 (CapacityInWords(kNew) / KBInWords), |
| 303 (UsedInWords(kOld) / KBInWords), |
| 304 (CapacityInWords(kOld) / KBInWords)); |
| 303 } | 305 } |
| 304 | 306 |
| 305 | 307 |
| 306 intptr_t Heap::Used(Space space) const { | 308 intptr_t Heap::UsedInWords(Space space) const { |
| 307 return space == kNew ? new_space_->in_use() : old_space_->in_use(); | 309 return space == kNew ? new_space_->UsedInWords() : old_space_->UsedInWords(); |
| 308 } | 310 } |
| 309 | 311 |
| 310 | 312 |
| 311 intptr_t Heap::Capacity(Space space) const { | 313 intptr_t Heap::CapacityInWords(Space space) const { |
| 312 return space == kNew ? new_space_->capacity() : old_space_->capacity(); | 314 return space == kNew ? new_space_->CapacityInWords() : |
| 315 old_space_->CapacityInWords(); |
| 313 } | 316 } |
| 314 | 317 |
| 315 | 318 |
| 316 void Heap::Profile(Dart_FileWriteCallback callback, void* stream) const { | 319 void Heap::Profile(Dart_FileWriteCallback callback, void* stream) const { |
| 317 HeapProfiler profiler(callback, stream); | 320 HeapProfiler profiler(callback, stream); |
| 318 | 321 |
| 319 // Dump the root set. | 322 // Dump the root set. |
| 320 HeapProfilerRootVisitor root_visitor(&profiler); | 323 HeapProfilerRootVisitor root_visitor(&profiler); |
| 321 Isolate* isolate = Isolate::Current(); | 324 Isolate* isolate = Isolate::Current(); |
| 322 Isolate* vm_isolate = Dart::vm_isolate(); | 325 Isolate* vm_isolate = Dart::vm_isolate(); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 } | 406 } |
| 404 | 407 |
| 405 | 408 |
| 406 void Heap::RecordBeforeGC(Space space, GCReason reason) { | 409 void Heap::RecordBeforeGC(Space space, GCReason reason) { |
| 407 ASSERT(!gc_in_progress_); | 410 ASSERT(!gc_in_progress_); |
| 408 gc_in_progress_ = true; | 411 gc_in_progress_ = true; |
| 409 stats_.num_++; | 412 stats_.num_++; |
| 410 stats_.space_ = space; | 413 stats_.space_ = space; |
| 411 stats_.reason_ = reason; | 414 stats_.reason_ = reason; |
| 412 stats_.before_.micros_ = OS::GetCurrentTimeMicros(); | 415 stats_.before_.micros_ = OS::GetCurrentTimeMicros(); |
| 413 stats_.before_.new_used_ = new_space_->in_use(); | 416 stats_.before_.new_used_in_words_ = new_space_->UsedInWords(); |
| 414 stats_.before_.new_capacity_ = new_space_->capacity(); | 417 stats_.before_.new_capacity_in_words_ = new_space_->CapacityInWords(); |
| 415 stats_.before_.old_used_ = old_space_->in_use(); | 418 stats_.before_.old_used_in_words_ = old_space_->UsedInWords(); |
| 416 stats_.before_.old_capacity_ = old_space_->capacity(); | 419 stats_.before_.old_capacity_in_words_ = old_space_->CapacityInWords(); |
| 417 stats_.times_[0] = 0; | 420 stats_.times_[0] = 0; |
| 418 stats_.times_[1] = 0; | 421 stats_.times_[1] = 0; |
| 419 stats_.times_[2] = 0; | 422 stats_.times_[2] = 0; |
| 420 stats_.times_[3] = 0; | 423 stats_.times_[3] = 0; |
| 421 stats_.data_[0] = 0; | 424 stats_.data_[0] = 0; |
| 422 stats_.data_[1] = 0; | 425 stats_.data_[1] = 0; |
| 423 stats_.data_[2] = 0; | 426 stats_.data_[2] = 0; |
| 424 stats_.data_[3] = 0; | 427 stats_.data_[3] = 0; |
| 425 } | 428 } |
| 426 | 429 |
| 427 | 430 |
| 428 void Heap::RecordAfterGC() { | 431 void Heap::RecordAfterGC() { |
| 429 stats_.after_.micros_ = OS::GetCurrentTimeMicros(); | 432 stats_.after_.micros_ = OS::GetCurrentTimeMicros(); |
| 430 stats_.after_.new_used_ = new_space_->in_use(); | 433 stats_.after_.new_used_in_words_ = new_space_->UsedInWords(); |
| 431 stats_.after_.new_capacity_ = new_space_->capacity(); | 434 stats_.after_.new_capacity_in_words_ = new_space_->CapacityInWords(); |
| 432 stats_.after_.old_used_ = old_space_->in_use(); | 435 stats_.after_.old_used_in_words_ = old_space_->UsedInWords(); |
| 433 stats_.after_.old_capacity_ = old_space_->capacity(); | 436 stats_.after_.old_capacity_in_words_ = old_space_->CapacityInWords(); |
| 434 ASSERT(gc_in_progress_); | 437 ASSERT(gc_in_progress_); |
| 435 gc_in_progress_ = false; | 438 gc_in_progress_ = false; |
| 436 } | 439 } |
| 437 | 440 |
| 438 | 441 |
| 439 static intptr_t RoundToKB(intptr_t memory_size) { | |
| 440 return (memory_size + (KB >> 1)) >> KBLog2; | |
| 441 } | |
| 442 | |
| 443 | |
| 444 static double RoundToSecs(int64_t micros) { | |
| 445 const int k1M = 1000000; // Converting us to secs. | |
| 446 return static_cast<double>(micros + (k1M / 2)) / k1M; | |
| 447 } | |
| 448 | |
| 449 | |
| 450 static double RoundToMillis(int64_t micros) { | |
| 451 const int k1K = 1000; // Conversting us to ms. | |
| 452 return static_cast<double>(micros + (k1K / 2)) / k1K; | |
| 453 } | |
| 454 | |
| 455 | |
| 456 void Heap::PrintStats() { | 442 void Heap::PrintStats() { |
| 457 if (!FLAG_verbose_gc) return; | 443 if (!FLAG_verbose_gc) return; |
| 458 Isolate* isolate = Isolate::Current(); | 444 Isolate* isolate = Isolate::Current(); |
| 459 | 445 |
| 460 if ((FLAG_verbose_gc_hdr != 0) && | 446 if ((FLAG_verbose_gc_hdr != 0) && |
| 461 (((stats_.num_ - 1) % FLAG_verbose_gc_hdr) == 0)) { | 447 (((stats_.num_ - 1) % FLAG_verbose_gc_hdr) == 0)) { |
| 462 OS::PrintErr("[ GC | space | count | start | gc time | " | 448 OS::PrintErr("[ GC | space | count | start | gc time | " |
| 463 "new gen (KB) | old gen (KB) | timers | data ]\n" | 449 "new gen (KB) | old gen (KB) | timers | data ]\n" |
| 464 "[ (isolate)| (reason)| | (s) | (ms) | " | 450 "[ (isolate)| (reason)| | (s) | (ms) | " |
| 465 " used , cap | used , cap | (ms) | ]\n"); | 451 " used , cap | used , cap | (ms) | ]\n"); |
| 466 } | 452 } |
| 467 | 453 |
| 468 const char* space_str = stats_.space_ == kNew ? "Scavenge" : "Mark-Sweep"; | 454 const char* space_str = stats_.space_ == kNew ? "Scavenge" : "Mark-Sweep"; |
| 469 OS::PrintErr( | 455 OS::PrintErr( |
| 470 "[ GC(%" Pd64 "): %s(%s), " // GC(isolate), space(reason) | 456 "[ GC(%" Pd64 "): %s(%s), " // GC(isolate), space(reason) |
| 471 "%" Pd ", " // count | 457 "%" Pd ", " // count |
| 472 "%.3f, " // start time | 458 "%.3f, " // start time |
| 473 "%.3f, " // total time | 459 "%.3f, " // total time |
| 474 "%" Pd ", %" Pd ", " // new gen: in use before/after | 460 "%" Pd ", %" Pd ", " // new gen: in use before/after |
| 475 "%" Pd ", %" Pd ", " // new gen: capacity before/after | 461 "%" Pd ", %" Pd ", " // new gen: capacity before/after |
| 476 "%" Pd ", %" Pd ", " // old gen: in use before/after | 462 "%" Pd ", %" Pd ", " // old gen: in use before/after |
| 477 "%" Pd ", %" Pd ", " // old gen: capacity before/after | 463 "%" Pd ", %" Pd ", " // old gen: capacity before/after |
| 478 "%.3f, %.3f, %.3f, %.3f, " // times | 464 "%.3f, %.3f, %.3f, %.3f, " // times |
| 479 "%" Pd ", %" Pd ", %" Pd ", %" Pd ", " // data | 465 "%" Pd ", %" Pd ", %" Pd ", %" Pd ", " // data |
| 480 "]\n", // End with a comma to make it easier to import in spreadsheets. | 466 "]\n", // End with a comma to make it easier to import in spreadsheets. |
| 481 isolate->main_port(), space_str, GCReasonToString(stats_.reason_), | 467 isolate->main_port(), space_str, GCReasonToString(stats_.reason_), |
| 482 stats_.num_, | 468 stats_.num_, |
| 483 RoundToSecs(stats_.before_.micros_ - isolate->start_time()), | 469 RoundMicrosecondsToSeconds(stats_.before_.micros_ - isolate->start_time()), |
| 484 RoundToMillis(stats_.after_.micros_ - stats_.before_.micros_), | 470 RoundMicrosecondsToMilliseconds(stats_.after_.micros_ - |
| 485 RoundToKB(stats_.before_.new_used_), RoundToKB(stats_.after_.new_used_), | 471 stats_.before_.micros_), |
| 486 RoundToKB(stats_.before_.new_capacity_), | 472 RoundWordsToKB(stats_.before_.new_used_in_words_), |
| 487 RoundToKB(stats_.after_.new_capacity_), | 473 RoundWordsToKB(stats_.after_.new_used_in_words_), |
| 488 RoundToKB(stats_.before_.old_used_), RoundToKB(stats_.after_.old_used_), | 474 RoundWordsToKB(stats_.before_.new_capacity_in_words_), |
| 489 RoundToKB(stats_.before_.old_capacity_), | 475 RoundWordsToKB(stats_.after_.new_capacity_in_words_), |
| 490 RoundToKB(stats_.after_.old_capacity_), | 476 RoundWordsToKB(stats_.before_.old_used_in_words_), |
| 491 RoundToMillis(stats_.times_[0]), | 477 RoundWordsToKB(stats_.after_.old_used_in_words_), |
| 492 RoundToMillis(stats_.times_[1]), | 478 RoundWordsToKB(stats_.before_.old_capacity_in_words_), |
| 493 RoundToMillis(stats_.times_[2]), | 479 RoundWordsToKB(stats_.after_.old_capacity_in_words_), |
| 494 RoundToMillis(stats_.times_[3]), | 480 RoundMicrosecondsToMilliseconds(stats_.times_[0]), |
| 481 RoundMicrosecondsToMilliseconds(stats_.times_[1]), |
| 482 RoundMicrosecondsToMilliseconds(stats_.times_[2]), |
| 483 RoundMicrosecondsToMilliseconds(stats_.times_[3]), |
| 495 stats_.data_[0], | 484 stats_.data_[0], |
| 496 stats_.data_[1], | 485 stats_.data_[1], |
| 497 stats_.data_[2], | 486 stats_.data_[2], |
| 498 stats_.data_[3]); | 487 stats_.data_[3]); |
| 499 } | 488 } |
| 500 | 489 |
| 501 | 490 |
| 502 #if defined(DEBUG) | 491 #if defined(DEBUG) |
| 503 NoGCScope::NoGCScope() : StackResource(Isolate::Current()) { | 492 NoGCScope::NoGCScope() : StackResource(Isolate::Current()) { |
| 504 isolate()->IncrementNoGCScopeDepth(); | 493 isolate()->IncrementNoGCScopeDepth(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 518 heap->DisableGrowthControl(); | 507 heap->DisableGrowthControl(); |
| 519 } | 508 } |
| 520 | 509 |
| 521 | 510 |
| 522 NoHeapGrowthControlScope::~NoHeapGrowthControlScope() { | 511 NoHeapGrowthControlScope::~NoHeapGrowthControlScope() { |
| 523 Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap(); | 512 Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap(); |
| 524 heap->SetGrowthControlState(current_growth_controller_state_); | 513 heap->SetGrowthControlState(current_growth_controller_state_); |
| 525 } | 514 } |
| 526 | 515 |
| 527 } // namespace dart | 516 } // namespace dart |
| OLD | NEW |