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 |