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/compiler_stats.h" | 9 #include "vm/compiler_stats.h" |
10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
11 #include "vm/heap_profiler.h" | 11 #include "vm/heap_profiler.h" |
12 #include "vm/heap_trace.h" | |
12 #include "vm/isolate.h" | 13 #include "vm/isolate.h" |
13 #include "vm/object.h" | 14 #include "vm/object.h" |
14 #include "vm/object_set.h" | 15 #include "vm/object_set.h" |
15 #include "vm/os.h" | 16 #include "vm/os.h" |
16 #include "vm/pages.h" | 17 #include "vm/pages.h" |
18 #include "vm/raw_object.h" | |
17 #include "vm/scavenger.h" | 19 #include "vm/scavenger.h" |
18 #include "vm/stack_frame.h" | 20 #include "vm/stack_frame.h" |
19 #include "vm/verifier.h" | 21 #include "vm/verifier.h" |
20 #include "vm/virtual_memory.h" | 22 #include "vm/virtual_memory.h" |
21 | 23 |
22 namespace dart { | 24 namespace dart { |
23 | 25 |
24 DEFINE_FLAG(bool, verbose_gc, false, "Enables verbose GC."); | 26 DEFINE_FLAG(bool, verbose_gc, false, "Enables verbose GC."); |
25 DEFINE_FLAG(bool, verify_before_gc, false, | 27 DEFINE_FLAG(bool, verify_before_gc, false, |
26 "Enables heap verification before GC."); | 28 "Enables heap verification before GC."); |
27 DEFINE_FLAG(bool, verify_after_gc, false, | 29 DEFINE_FLAG(bool, verify_after_gc, false, |
28 "Enables heap verification after GC."); | 30 "Enables heap verification after GC."); |
29 DEFINE_FLAG(bool, gc_at_alloc, false, "GC at every allocation."); | 31 DEFINE_FLAG(bool, gc_at_alloc, false, "GC at every allocation."); |
30 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," |
31 "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"); |
32 DEFINE_FLAG(int, old_gen_heap_size, Heap::kHeapSizeInMB, | 34 DEFINE_FLAG(int, old_gen_heap_size, Heap::kHeapSizeInMB, |
33 "old gen heap size in MB," | 35 "old gen heap size in MB," |
34 "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"); |
35 | 37 |
36 Heap::Heap() : read_only_(false) { | 38 Heap::Heap() : read_only_(false) { |
37 new_space_ = new Scavenger(this, | 39 new_space_ = new Scavenger(this, |
38 (FLAG_new_gen_heap_size * MB), | 40 (FLAG_new_gen_heap_size * MB), |
39 kNewObjectAlignmentOffset); | 41 kNewObjectAlignmentOffset); |
40 old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MB)); | 42 old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MB)); |
43 heap_trace_ = HeapTrace::is_enabled() ? new HeapTrace : NULL; | |
siva
2012/12/05 16:06:40
new HeapTrace() ?
cshapiro
2012/12/08 03:23:08
Parenthesis are not required. We do not put paren
| |
41 } | 44 } |
42 | 45 |
43 | 46 |
44 Heap::~Heap() { | 47 Heap::~Heap() { |
45 delete new_space_; | 48 delete new_space_; |
46 delete old_space_; | 49 delete old_space_; |
47 } | 50 } |
48 | 51 |
49 | 52 |
50 uword Heap::AllocateNew(intptr_t size) { | 53 uword Heap::AllocateNew(intptr_t size) { |
51 ASSERT(Isolate::Current()->no_gc_scope_depth() == 0); | 54 ASSERT(Isolate::Current()->no_gc_scope_depth() == 0); |
52 uword addr = new_space_->TryAllocate(size); | 55 uword addr = new_space_->TryAllocate(size); |
53 if (addr != 0) { | 56 if (addr == 0) { |
54 return addr; | 57 CollectGarbage(kNew); |
58 addr = new_space_->TryAllocate(size); | |
59 if (addr == 0) { | |
60 return AllocateOld(size, HeapPage::kData); | |
61 } | |
55 } | 62 } |
56 CollectGarbage(kNew); | 63 if (HeapTrace::is_enabled()) { |
57 addr = new_space_->TryAllocate(size); | 64 heap_trace_->TraceAllocation(addr, size); |
58 if (addr != 0) { | |
59 return addr; | |
60 } | 65 } |
61 return AllocateOld(size, HeapPage::kData); | 66 return addr; |
62 } | 67 } |
63 | 68 |
64 | 69 |
65 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) { | 70 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) { |
66 ASSERT(Isolate::Current()->no_gc_scope_depth() == 0); | 71 ASSERT(Isolate::Current()->no_gc_scope_depth() == 0); |
67 uword addr = old_space_->TryAllocate(size, type); | 72 uword addr = old_space_->TryAllocate(size, type); |
68 if (addr == 0) { | 73 if (addr == 0) { |
69 CollectAllGarbage(); | 74 CollectAllGarbage(); |
70 addr = old_space_->TryAllocate(size, type, PageSpace::kForceGrowth); | 75 addr = old_space_->TryAllocate(size, type, PageSpace::kForceGrowth); |
71 if (addr == 0) { | 76 if (addr == 0) { |
72 OS::PrintErr("Exhausted heap space, trying to allocate %"Pd" bytes.\n", | 77 OS::PrintErr("Exhausted heap space, trying to allocate %"Pd" bytes.\n", |
73 size); | 78 size); |
79 return 0; | |
74 } | 80 } |
75 } | 81 } |
82 if (HeapTrace::is_enabled()) { | |
83 heap_trace_->TraceAllocation(addr, size); | |
84 } | |
76 return addr; | 85 return addr; |
77 } | 86 } |
78 | 87 |
79 | 88 |
80 bool Heap::Contains(uword addr) const { | 89 bool Heap::Contains(uword addr) const { |
81 return new_space_->Contains(addr) || | 90 return new_space_->Contains(addr) || |
82 old_space_->Contains(addr); | 91 old_space_->Contains(addr); |
83 } | 92 } |
84 | 93 |
85 | 94 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
261 | 270 |
262 | 271 |
263 void Heap::PrintSizes() const { | 272 void Heap::PrintSizes() const { |
264 OS::PrintErr("New space (%"Pd"k of %"Pd"k) " | 273 OS::PrintErr("New space (%"Pd"k of %"Pd"k) " |
265 "Old space (%"Pd"k of %"Pd"k)\n", | 274 "Old space (%"Pd"k of %"Pd"k)\n", |
266 (new_space_->in_use() / KB), (new_space_->capacity() / KB), | 275 (new_space_->in_use() / KB), (new_space_->capacity() / KB), |
267 (old_space_->in_use() / KB), (old_space_->capacity() / KB)); | 276 (old_space_->in_use() / KB), (old_space_->capacity() / KB)); |
268 } | 277 } |
269 | 278 |
270 | 279 |
271 void Heap::Profile(Dart_HeapProfileWriteCallback callback, void* stream) const { | 280 void Heap::Profile(Dart_FileWriteCallback callback, void* stream) const { |
272 HeapProfiler profiler(callback, stream); | 281 HeapProfiler profiler(callback, stream); |
273 | 282 |
274 // Dump the root set. | 283 // Dump the root set. |
275 HeapProfilerRootVisitor root_visitor(&profiler); | 284 HeapProfilerRootVisitor root_visitor(&profiler); |
276 Isolate* isolate = Isolate::Current(); | 285 Isolate* isolate = Isolate::Current(); |
277 Isolate* vm_isolate = Dart::vm_isolate(); | 286 Isolate* vm_isolate = Dart::vm_isolate(); |
278 isolate->VisitObjectPointers(&root_visitor, false, | 287 isolate->VisitObjectPointers(&root_visitor, false, |
279 StackFrameIterator::kDontValidateFrames); | 288 StackFrameIterator::kDontValidateFrames); |
280 HeapProfilerWeakRootVisitor weak_root_visitor(&root_visitor); | 289 HeapProfilerWeakRootVisitor weak_root_visitor(&root_visitor); |
281 isolate->VisitWeakPersistentHandles(&weak_root_visitor, true); | 290 isolate->VisitWeakPersistentHandles(&weak_root_visitor, true); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 isolate()->IncrementNoGCScopeDepth(); | 348 isolate()->IncrementNoGCScopeDepth(); |
340 } | 349 } |
341 | 350 |
342 | 351 |
343 NoGCScope::~NoGCScope() { | 352 NoGCScope::~NoGCScope() { |
344 isolate()->DecrementNoGCScopeDepth(); | 353 isolate()->DecrementNoGCScopeDepth(); |
345 } | 354 } |
346 #endif // defined(DEBUG) | 355 #endif // defined(DEBUG) |
347 | 356 |
348 } // namespace dart | 357 } // namespace dart |
OLD | NEW |