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

Side by Side Diff: runtime/vm/heap.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/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_profiler.h" 10 #include "vm/heap_profiler.h"
11 #include "vm/heap_trace.h" 11 #include "vm/heap_trace.h"
12 #include "vm/isolate.h" 12 #include "vm/isolate.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 #include "vm/object_set.h" 14 #include "vm/object_set.h"
15 #include "vm/os.h" 15 #include "vm/os.h"
16 #include "vm/pages.h" 16 #include "vm/pages.h"
17 #include "vm/raw_object.h" 17 #include "vm/raw_object.h"
18 #include "vm/scavenger.h" 18 #include "vm/scavenger.h"
19 #include "vm/stack_frame.h" 19 #include "vm/stack_frame.h"
20 #include "vm/verifier.h" 20 #include "vm/verifier.h"
21 #include "vm/virtual_memory.h" 21 #include "vm/virtual_memory.h"
22 22
23 namespace dart { 23 namespace dart {
24 24
25 DEFINE_FLAG(bool, verbose_gc, false, "Enables verbose GC."); 25 DEFINE_FLAG(bool, verbose_gc, false, "Enables verbose GC.");
26 DEFINE_FLAG(int, verbose_gc_hdr, 40, "Print verbose GC header interval.");
26 DEFINE_FLAG(bool, verify_before_gc, false, 27 DEFINE_FLAG(bool, verify_before_gc, false,
27 "Enables heap verification before GC."); 28 "Enables heap verification before GC.");
28 DEFINE_FLAG(bool, verify_after_gc, false, 29 DEFINE_FLAG(bool, verify_after_gc, false,
29 "Enables heap verification after GC."); 30 "Enables heap verification after GC.");
30 DEFINE_FLAG(bool, gc_at_alloc, false, "GC at every allocation."); 31 DEFINE_FLAG(bool, gc_at_alloc, false, "GC at every allocation.");
31 DEFINE_FLAG(int, new_gen_heap_size, 32, "new gen heap size in MB," 32 DEFINE_FLAG(int, new_gen_heap_size, 32, "new gen heap size in MB,"
32 "e.g: --new_gen_heap_size=64 allocates a 64MB new gen heap"); 33 "e.g: --new_gen_heap_size=64 allocates a 64MB new gen heap");
33 DEFINE_FLAG(int, old_gen_heap_size, Heap::kHeapSizeInMB, 34 DEFINE_FLAG(int, old_gen_heap_size, Heap::kHeapSizeInMB,
34 "old gen heap size in MB," 35 "old gen heap size in MB,"
35 "e.g: --old_gen_heap_size=1024 allocates a 1024MB old gen heap"); 36 "e.g: --old_gen_heap_size=1024 allocates a 1024MB old gen heap");
36 37
37 Heap::Heap() : read_only_(false) { 38 Heap::Heap() : read_only_(false) {
38 new_space_ = new Scavenger(this, 39 new_space_ = new Scavenger(this,
39 (FLAG_new_gen_heap_size * MB), 40 (FLAG_new_gen_heap_size * MB),
40 kNewObjectAlignmentOffset); 41 kNewObjectAlignmentOffset);
41 old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MB)); 42 old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MB));
43 stats_.num_ = 0;
42 heap_trace_ = new HeapTrace; 44 heap_trace_ = new HeapTrace;
43 } 45 }
44 46
45 47
46 Heap::~Heap() { 48 Heap::~Heap() {
47 delete new_space_; 49 delete new_space_;
48 delete old_space_; 50 delete old_space_;
49 } 51 }
50 52
51 53
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 ASSERT((raw_obj == Object::null()) || 146 ASSERT((raw_obj == Object::null()) ||
145 (raw_obj->GetClassId() == kInstructionsCid)); 147 (raw_obj->GetClassId() == kInstructionsCid));
146 return reinterpret_cast<RawInstructions*>(raw_obj); 148 return reinterpret_cast<RawInstructions*>(raw_obj);
147 } 149 }
148 150
149 151
150 void Heap::CollectGarbage(Space space, ApiCallbacks api_callbacks) { 152 void Heap::CollectGarbage(Space space, ApiCallbacks api_callbacks) {
151 bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks); 153 bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
152 switch (space) { 154 switch (space) {
153 case kNew: { 155 case kNew: {
154 new_space_->Scavenge(invoke_api_callbacks, 156 RecordBeforeGC(kNew, kNewSpace);
155 GCReasonToString(kNewSpace)); 157 new_space_->Scavenge(invoke_api_callbacks);
158 RecordAfterGC();
159 PrintStats();
156 if (new_space_->HadPromotionFailure()) { 160 if (new_space_->HadPromotionFailure()) {
157 old_space_->MarkSweep(true, 161 CollectGarbage(kOld, api_callbacks);
158 GCReasonToString(kPromotionFailure));
159 } 162 }
160 break; 163 break;
161 } 164 }
162 case kOld: 165 case kOld:
163 case kCode: 166 case kCode: {
164 old_space_->MarkSweep(invoke_api_callbacks, 167 bool promotion_failure = new_space_->HadPromotionFailure();
165 GCReasonToString(kOldSpace)); 168 RecordBeforeGC(kOld, promotion_failure ? kPromotionFailure : kOldSpace);
169 old_space_->MarkSweep(invoke_api_callbacks);
170 RecordAfterGC();
171 PrintStats();
166 break; 172 break;
173 }
167 default: 174 default:
168 UNREACHABLE(); 175 UNREACHABLE();
169 } 176 }
170 if (FLAG_verbose_gc) {
171 PrintSizes();
172 }
173 } 177 }
174 178
175 179
176 void Heap::CollectGarbage(Space space) { 180 void Heap::CollectGarbage(Space space) {
177 ApiCallbacks api_callbacks; 181 ApiCallbacks api_callbacks;
178 if (space == kOld) { 182 if (space == kOld) {
179 api_callbacks = kInvokeApiCallbacks; 183 api_callbacks = kInvokeApiCallbacks;
180 } else { 184 } else {
181 api_callbacks = kIgnoreApiCallbacks; 185 api_callbacks = kIgnoreApiCallbacks;
182 } 186 }
183 CollectGarbage(space, api_callbacks); 187 CollectGarbage(space, api_callbacks);
184 } 188 }
185 189
186 190
187 void Heap::CollectAllGarbage() { 191 void Heap::CollectAllGarbage() {
188 const char* gc_reason = GCReasonToString(kFull); 192 RecordBeforeGC(kNew, kFull);
189 new_space_->Scavenge(kInvokeApiCallbacks, gc_reason); 193 new_space_->Scavenge(kInvokeApiCallbacks);
190 old_space_->MarkSweep(kInvokeApiCallbacks, gc_reason); 194 RecordAfterGC();
191 if (FLAG_verbose_gc) { 195 PrintStats();
192 PrintSizes(); 196 RecordBeforeGC(kOld, kFull);
193 } 197 old_space_->MarkSweep(kInvokeApiCallbacks);
198 RecordAfterGC();
199 PrintStats();
194 } 200 }
195 201
196 202
197 void Heap::EnableGrowthControl() { 203 void Heap::EnableGrowthControl() {
198 old_space_->EnableGrowthControl(); 204 old_space_->EnableGrowthControl();
199 } 205 }
200 206
201 207
202 void Heap::WriteProtect(bool read_only) { 208 void Heap::WriteProtect(bool read_only) {
203 read_only_ = read_only; 209 read_only_ = read_only;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 322
317 323
318 const char* Heap::GCReasonToString(GCReason gc_reason) { 324 const char* Heap::GCReasonToString(GCReason gc_reason) {
319 switch (gc_reason) { 325 switch (gc_reason) {
320 case kNewSpace: 326 case kNewSpace:
321 return "new space"; 327 return "new space";
322 case kPromotionFailure: 328 case kPromotionFailure:
323 return "promotion failure"; 329 return "promotion failure";
324 case kOldSpace: 330 case kOldSpace:
325 return "old space"; 331 return "old space";
326 case kCodeSpace:
327 return "code space";
328 case kFull: 332 case kFull:
329 return "full"; 333 return "full";
330 case kGCAtAlloc: 334 case kGCAtAlloc:
331 return "debugging"; 335 return "debugging";
332 case kGCTestCase: 336 case kGCTestCase:
333 return "test case"; 337 return "test case";
334 default: 338 default:
335 UNREACHABLE(); 339 UNREACHABLE();
336 return ""; 340 return "";
337 } 341 }
(...skipping 17 matching lines...) Expand all
355 ASSERT(raw_obj->IsOldObject()); 359 ASSERT(raw_obj->IsOldObject());
356 return old_space_->GetPeer(raw_obj); 360 return old_space_->GetPeer(raw_obj);
357 } 361 }
358 362
359 363
360 int64_t Heap::PeerCount() const { 364 int64_t Heap::PeerCount() const {
361 return new_space_->PeerCount() + old_space_->PeerCount(); 365 return new_space_->PeerCount() + old_space_->PeerCount();
362 } 366 }
363 367
364 368
369 void Heap::RecordBeforeGC(Space space, GCReason reason) {
370 stats_.num_++;
371 stats_.space_ = space;
372 stats_.reason_ = reason;
373 stats_.before_.micros_ = OS::GetCurrentTimeMicros();
374 stats_.before_.new_used_ = new_space_->in_use();
375 stats_.before_.new_capacity_ = new_space_->capacity();
376 stats_.before_.old_used_ = old_space_->in_use();
377 stats_.before_.old_capacity_ = old_space_->capacity();
378 stats_.times_[0] = 0;
379 stats_.times_[1] = 0;
380 stats_.times_[2] = 0;
381 stats_.times_[3] = 0;
382 stats_.data_[0] = 0;
383 stats_.data_[1] = 0;
384 stats_.data_[2] = 0;
385 stats_.data_[3] = 0;
386 }
387
388
389 void Heap::RecordAfterGC() {
390 stats_.after_.micros_ = OS::GetCurrentTimeMicros();
391 stats_.after_.new_used_ = new_space_->in_use();
392 stats_.after_.new_capacity_ = new_space_->capacity();
393 stats_.after_.old_used_ = old_space_->in_use();
394 stats_.after_.old_capacity_ = old_space_->capacity();
395 }
396
397
398 static intptr_t RoundToKB(intptr_t memory_size) {
399 return (memory_size + (KB >> 1)) >> KBLog2;
400 }
401
402
403 static double RoundToSecs(int64_t micros) {
404 const int k1M = 1000000; // Converting us to secs.
405 return static_cast<double>(micros + (k1M / 2)) / k1M;
406 }
407
408
409 static double RoundToMillis(int64_t micros) {
410 const int k1K = 1000; // Conversting us to ms.
411 return static_cast<double>(micros + (k1K / 2)) / k1K;
412 }
413
414
415 void Heap::PrintStats() {
416 if (!FLAG_verbose_gc) return;
417 Isolate* isolate = Isolate::Current();
418
419 if ((FLAG_verbose_gc_hdr != 0) &&
420 (((stats_.num_ - 1) % FLAG_verbose_gc_hdr) == 0)) {
421 OS::PrintErr("[ GC | space | count | start | gc time | "
422 "new gen (KB) | old gen (KB) | timers | data ]\n"
423 "[ (isolate)| (reason)| | (s) | (ms) | "
424 " used , cap | used , cap | (ms) | ]\n");
425 }
426
427 const char* space_str = stats_.space_ == kNew ? "Scavenge" : "Mark-Sweep";
428 OS::PrintErr(
429 "[ GC(%"Pd64"): %s(%s), " // GC(isolate), space(reason)
430 "%"Pd", " // count
431 "%.3f, " // start time
432 "%.3f, " // total time
433 "%"Pd", %"Pd", %"Pd", %"Pd", " // new gen: in use, capacity before/after
434 "%"Pd", %"Pd", %"Pd", %"Pd", " // old gen: in use, capacity before/after
435 "%.3f, %.3f, %.3f, %.3f, " // times
436 "%"Pd", %"Pd", %"Pd", %"Pd", " // data
437 "]\n", // End with a comma to make it easier to import in spreadsheets.
438 isolate->main_port(), space_str, GCReasonToString(stats_.reason_),
439 stats_.num_,
440 RoundToSecs(stats_.before_.micros_ - isolate->start_time()),
441 RoundToMillis(stats_.after_.micros_ - stats_.before_.micros_),
442 RoundToKB(stats_.before_.new_used_), RoundToKB(stats_.after_.new_used_),
443 RoundToKB(stats_.before_.new_capacity_),
444 RoundToKB(stats_.after_.new_capacity_),
445 RoundToKB(stats_.before_.old_used_), RoundToKB(stats_.after_.old_used_),
446 RoundToKB(stats_.before_.old_capacity_),
447 RoundToKB(stats_.after_.old_capacity_),
448 RoundToMillis(stats_.times_[0]),
449 RoundToMillis(stats_.times_[1]),
450 RoundToMillis(stats_.times_[2]),
451 RoundToMillis(stats_.times_[3]),
452 stats_.data_[0],
453 stats_.data_[1],
454 stats_.data_[2],
455 stats_.data_[3]);
456 }
457
458
365 #if defined(DEBUG) 459 #if defined(DEBUG)
366 NoGCScope::NoGCScope() : StackResource(Isolate::Current()) { 460 NoGCScope::NoGCScope() : StackResource(Isolate::Current()) {
367 isolate()->IncrementNoGCScopeDepth(); 461 isolate()->IncrementNoGCScopeDepth();
368 } 462 }
369 463
370 464
371 NoGCScope::~NoGCScope() { 465 NoGCScope::~NoGCScope() {
372 isolate()->DecrementNoGCScopeDepth(); 466 isolate()->DecrementNoGCScopeDepth();
373 } 467 }
374 #endif // defined(DEBUG) 468 #endif // defined(DEBUG)
375 469
376 } // namespace dart 470 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698