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

Side by Side Diff: vm/heap.cc

Issue 11265026: - Consolidate code into the old generation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 1 month 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
« vm/gc_sweeper.cc ('K') | « vm/heap.h ('k') | vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/compiler_stats.h" 9 #include "vm/compiler_stats.h"
10 #include "vm/flags.h" 10 #include "vm/flags.h"
(...skipping 14 matching lines...) Expand all
25 DEFINE_FLAG(bool, verify_before_gc, false, 25 DEFINE_FLAG(bool, verify_before_gc, false,
26 "Enables heap verification before GC."); 26 "Enables heap verification before GC.");
27 DEFINE_FLAG(bool, verify_after_gc, false, 27 DEFINE_FLAG(bool, verify_after_gc, false,
28 "Enables heap verification after GC."); 28 "Enables heap verification after GC.");
29 DEFINE_FLAG(bool, gc_at_alloc, false, "GC at every allocation."); 29 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," 30 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"); 31 "e.g: --new_gen_heap_size=64 allocates a 64MB new gen heap");
32 DEFINE_FLAG(int, old_gen_heap_size, Heap::kHeapSizeInMB, 32 DEFINE_FLAG(int, old_gen_heap_size, Heap::kHeapSizeInMB,
33 "old gen heap size in MB," 33 "old gen heap size in MB,"
34 "e.g: --old_gen_heap_size=1024 allocates a 1024MB old gen heap"); 34 "e.g: --old_gen_heap_size=1024 allocates a 1024MB old gen heap");
35 DEFINE_FLAG(int, code_heap_size, Heap::kCodeHeapSizeInMB,
36 "code heap size in MB,"
37 "e.g: --code_heap_size=8 allocates a 8MB code heap");
38 35
39 Heap::Heap() : read_only_(false) { 36 Heap::Heap() : read_only_(false) {
40 new_space_ = new Scavenger(this, 37 new_space_ = new Scavenger(this,
41 (FLAG_new_gen_heap_size * MB), 38 (FLAG_new_gen_heap_size * MB),
42 kNewObjectAlignmentOffset); 39 kNewObjectAlignmentOffset);
43 old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MB)); 40 old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MB));
44 code_space_ = new PageSpace(this, (FLAG_code_heap_size * MB), true);
45 } 41 }
46 42
47 43
48 Heap::~Heap() { 44 Heap::~Heap() {
49 delete new_space_; 45 delete new_space_;
50 delete old_space_; 46 delete old_space_;
51 delete code_space_;
52 } 47 }
53 48
54 49
55 uword Heap::AllocateNew(intptr_t size) { 50 uword Heap::AllocateNew(intptr_t size) {
56 ASSERT(Isolate::Current()->no_gc_scope_depth() == 0); 51 ASSERT(Isolate::Current()->no_gc_scope_depth() == 0);
57 uword addr = new_space_->TryAllocate(size); 52 uword addr = new_space_->TryAllocate(size);
58 if (addr != 0) { 53 if (addr != 0) {
59 return addr; 54 return addr;
60 } 55 }
61 CollectGarbage(kNew); 56 CollectGarbage(kNew);
62 addr = new_space_->TryAllocate(size); 57 addr = new_space_->TryAllocate(size);
63 if (addr != 0) { 58 if (addr != 0) {
64 return addr; 59 return addr;
65 } 60 }
66 return AllocateOld(size); 61 return AllocateOld(size, HeapPage::kData);
67 } 62 }
68 63
69 64
70 uword Heap::AllocateOld(intptr_t size) { 65 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) {
71 ASSERT(Isolate::Current()->no_gc_scope_depth() == 0); 66 ASSERT(Isolate::Current()->no_gc_scope_depth() == 0);
72 uword addr = old_space_->TryAllocate(size); 67 uword addr = old_space_->TryAllocate(size, type);
73 if (addr == 0) { 68 if (addr == 0) {
74 CollectAllGarbage(); 69 CollectAllGarbage();
75 addr = old_space_->TryAllocate(size, PageSpace::kForceGrowth); 70 addr = old_space_->TryAllocate(size, type, PageSpace::kForceGrowth);
76 if (addr == 0) { 71 if (addr == 0) {
77 OS::PrintErr("Exhausted heap space, trying to allocate %"Pd" bytes.\n", 72 OS::PrintErr("Exhausted heap space, trying to allocate %"Pd" bytes.\n",
78 size); 73 size);
79 } 74 }
80 } 75 }
81 return addr; 76 return addr;
82 } 77 }
83 78
84 79
85 uword Heap::AllocateCode(PageSpace* space, intptr_t size) {
86 ASSERT(Isolate::Current()->no_gc_scope_depth() == 0);
87 ASSERT(Utils::IsAligned(size, OS::PreferredCodeAlignment()));
88 uword addr = space->TryAllocate(size);
89 if (addr == 0) {
90 // TODO(iposva): Support GC.
91 FATAL("Exhausted code heap space.");
92 }
93 if (FLAG_compiler_stats) {
94 CompilerStats::code_allocated += size;
95 }
96 return addr;
97 }
98
99
100 bool Heap::Contains(uword addr) const { 80 bool Heap::Contains(uword addr) const {
101 return new_space_->Contains(addr) || 81 return new_space_->Contains(addr) ||
102 old_space_->Contains(addr) || 82 old_space_->Contains(addr);
103 code_space_->Contains(addr);
104 } 83 }
105 84
106 85
107 bool Heap::NewContains(uword addr) const { 86 bool Heap::NewContains(uword addr) const {
108 return new_space_->Contains(addr); 87 return new_space_->Contains(addr);
109 } 88 }
110 89
111 90
112 bool Heap::OldContains(uword addr) const { 91 bool Heap::OldContains(uword addr) const {
113 return old_space_->Contains(addr); 92 return old_space_->Contains(addr);
114 } 93 }
115 94
116 95
117 bool Heap::CodeContains(uword addr) const { 96 bool Heap::CodeContains(uword addr) const {
118 return code_space_->Contains(addr); 97 return old_space_->Contains(addr, HeapPage::kExecutable);
119 } 98 }
120 99
121 100
122 void Heap::IterateObjects(ObjectVisitor* visitor) { 101 void Heap::IterateObjects(ObjectVisitor* visitor) {
123 new_space_->VisitObjects(visitor); 102 new_space_->VisitObjects(visitor);
124 old_space_->VisitObjects(visitor); 103 old_space_->VisitObjects(visitor);
125 code_space_->VisitObjects(visitor);
126 } 104 }
127 105
128 106
129 void Heap::IteratePointers(ObjectPointerVisitor* visitor) { 107 void Heap::IteratePointers(ObjectPointerVisitor* visitor) {
130 new_space_->VisitObjectPointers(visitor); 108 new_space_->VisitObjectPointers(visitor);
131 old_space_->VisitObjectPointers(visitor); 109 old_space_->VisitObjectPointers(visitor);
132 code_space_->VisitObjectPointers(visitor);
133 } 110 }
134 111
135 112
136 void Heap::IterateNewPointers(ObjectPointerVisitor* visitor) { 113 void Heap::IterateNewPointers(ObjectPointerVisitor* visitor) {
137 new_space_->VisitObjectPointers(visitor); 114 new_space_->VisitObjectPointers(visitor);
138 } 115 }
139 116
140 117
141 void Heap::IterateOldPointers(ObjectPointerVisitor* visitor) { 118 void Heap::IterateOldPointers(ObjectPointerVisitor* visitor) {
142 old_space_->VisitObjectPointers(visitor); 119 old_space_->VisitObjectPointers(visitor);
143 code_space_->VisitObjectPointers(visitor);
144 }
145
146
147 void Heap::IterateCodePointers(ObjectPointerVisitor* visitor) {
148 code_space_->VisitObjectPointers(visitor);
149 } 120 }
150 121
151 122
152 void Heap::IterateNewObjects(ObjectVisitor* visitor) { 123 void Heap::IterateNewObjects(ObjectVisitor* visitor) {
153 new_space_->VisitObjects(visitor); 124 new_space_->VisitObjects(visitor);
154 } 125 }
155 126
156 127
157 void Heap::IterateOldObjects(ObjectVisitor* visitor) { 128 void Heap::IterateOldObjects(ObjectVisitor* visitor) {
158 old_space_->VisitObjects(visitor); 129 old_space_->VisitObjects(visitor);
159 code_space_->VisitObjects(visitor);
160 }
161
162
163 void Heap::IterateCodeObjects(ObjectVisitor* visitor) {
164 code_space_->VisitObjects(visitor);
165 } 130 }
166 131
167 132
168 RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) { 133 RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) {
169 // The code heap can only have RawInstructions objects. 134 // Only executable pages can have RawInstructions objects.
170 RawObject* raw_obj = code_space_->FindObject(visitor); 135 RawObject* raw_obj = old_space_->FindObject(visitor, HeapPage::kExecutable);
171 ASSERT((raw_obj == Object::null()) || 136 ASSERT((raw_obj == Object::null()) ||
172 (raw_obj->GetClassId() == kInstructionsCid)); 137 (raw_obj->GetClassId() == kInstructionsCid));
173 return reinterpret_cast<RawInstructions*>(raw_obj); 138 return reinterpret_cast<RawInstructions*>(raw_obj);
174 } 139 }
175 140
176 141
177 void Heap::CollectGarbage(Space space, ApiCallbacks api_callbacks) { 142 void Heap::CollectGarbage(Space space, ApiCallbacks api_callbacks) {
178 bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks); 143 bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
179 switch (space) { 144 switch (space) {
180 case kNew: { 145 case kNew: {
181 new_space_->Scavenge(invoke_api_callbacks, 146 new_space_->Scavenge(invoke_api_callbacks,
182 GCReasonToString(kNewSpace)); 147 GCReasonToString(kNewSpace));
183 if (new_space_->HadPromotionFailure()) { 148 if (new_space_->HadPromotionFailure()) {
184 old_space_->MarkSweep(true, 149 old_space_->MarkSweep(true,
185 GCReasonToString(kPromotionFailure)); 150 GCReasonToString(kPromotionFailure));
186 } 151 }
187 break; 152 break;
188 } 153 }
189 case kOld: 154 case kOld:
155 case kCode:
190 old_space_->MarkSweep(invoke_api_callbacks, 156 old_space_->MarkSweep(invoke_api_callbacks,
191 GCReasonToString(kOldSpace)); 157 GCReasonToString(kOldSpace));
192 break; 158 break;
193 case kCode:
194 UNIMPLEMENTED();
195 code_space_->MarkSweep(invoke_api_callbacks,
196 GCReasonToString(kCodeSpace));
197 break;
198 default: 159 default:
199 UNREACHABLE(); 160 UNREACHABLE();
200 } 161 }
201 if (FLAG_verbose_gc) { 162 if (FLAG_verbose_gc) {
202 PrintSizes(); 163 PrintSizes();
203 } 164 }
204 } 165 }
205 166
206 167
207 void Heap::CollectGarbage(Space space) { 168 void Heap::CollectGarbage(Space space) {
208 ApiCallbacks api_callbacks; 169 ApiCallbacks api_callbacks;
209 if (space == kOld) { 170 if (space == kOld) {
210 api_callbacks = kInvokeApiCallbacks; 171 api_callbacks = kInvokeApiCallbacks;
211 } else { 172 } else {
212 api_callbacks = kIgnoreApiCallbacks; 173 api_callbacks = kIgnoreApiCallbacks;
213 } 174 }
214 CollectGarbage(space, api_callbacks); 175 CollectGarbage(space, api_callbacks);
215 } 176 }
216 177
217 178
218 void Heap::CollectAllGarbage() { 179 void Heap::CollectAllGarbage() {
219 const char* gc_reason = GCReasonToString(kFull); 180 const char* gc_reason = GCReasonToString(kFull);
220 new_space_->Scavenge(kInvokeApiCallbacks, gc_reason); 181 new_space_->Scavenge(kInvokeApiCallbacks, gc_reason);
221 old_space_->MarkSweep(kInvokeApiCallbacks, gc_reason); 182 old_space_->MarkSweep(kInvokeApiCallbacks, gc_reason);
222 // TODO(iposva): Merge old and code space.
223 // code_space_->MarkSweep(kInvokeApiCallbacks, gc_reason);
224 if (FLAG_verbose_gc) { 183 if (FLAG_verbose_gc) {
225 PrintSizes(); 184 PrintSizes();
226 } 185 }
227 } 186 }
228 187
229 188
230 void Heap::EnableGrowthControl() { 189 void Heap::EnableGrowthControl() {
231 old_space_->EnableGrowthControl(); 190 old_space_->EnableGrowthControl();
232 } 191 }
233 192
234 193
235 void Heap::WriteProtect(bool read_only) { 194 void Heap::WriteProtect(bool read_only) {
236 read_only_ = read_only; 195 read_only_ = read_only;
237 new_space_->WriteProtect(read_only); 196 new_space_->WriteProtect(read_only);
238 old_space_->WriteProtect(read_only); 197 old_space_->WriteProtect(read_only);
239 // TODO(iposva): Merge old and code space.
240 // code_space_->WriteProtect(read_only);
241 } 198 }
242 199
243 200
244 uword Heap::TopAddress() { 201 uword Heap::TopAddress() {
245 return reinterpret_cast<uword>(new_space_->TopAddress()); 202 return reinterpret_cast<uword>(new_space_->TopAddress());
246 } 203 }
247 204
248 205
249 uword Heap::EndAddress() { 206 uword Heap::EndAddress() {
250 return reinterpret_cast<uword>(new_space_->EndAddress()); 207 return reinterpret_cast<uword>(new_space_->EndAddress());
(...skipping 10 matching lines...) Expand all
261 void Heap::StartEndAddress(uword* start, uword* end) const { 218 void Heap::StartEndAddress(uword* start, uword* end) const {
262 ASSERT(new_space_->capacity() != 0); 219 ASSERT(new_space_->capacity() != 0);
263 new_space_->StartEndAddress(start, end); 220 new_space_->StartEndAddress(start, end);
264 if (old_space_->capacity() != 0) { 221 if (old_space_->capacity() != 0) {
265 uword old_start; 222 uword old_start;
266 uword old_end; 223 uword old_end;
267 old_space_->StartEndAddress(&old_start, &old_end); 224 old_space_->StartEndAddress(&old_start, &old_end);
268 *start = Utils::Minimum(old_start, *start); 225 *start = Utils::Minimum(old_start, *start);
269 *end = Utils::Maximum(old_end, *end); 226 *end = Utils::Maximum(old_end, *end);
270 } 227 }
271 if (code_space_->capacity() != 0) {
272 uword code_start;
273 uword code_end;
274 code_space_->StartEndAddress(&code_start, &code_end);
275 *start = Utils::Minimum(code_start, *start);
276 *end = Utils::Maximum(code_end, *end);
277 }
278 ASSERT(*start <= *end); 228 ASSERT(*start <= *end);
279 } 229 }
280 230
281 231
282 ObjectSet* Heap::CreateAllocatedObjectSet() const { 232 ObjectSet* Heap::CreateAllocatedObjectSet() const {
283 Isolate* isolate = Isolate::Current(); 233 Isolate* isolate = Isolate::Current();
284 uword start, end; 234 uword start, end;
285 isolate->heap()->StartEndAddress(&start, &end); 235 isolate->heap()->StartEndAddress(&start, &end);
286 236
287 Isolate* vm_isolate = Dart::vm_isolate(); 237 Isolate* vm_isolate = Dart::vm_isolate();
(...skipping 17 matching lines...) Expand all
305 VerifyPointersVisitor visitor(isolate, allocated_set); 255 VerifyPointersVisitor visitor(isolate, allocated_set);
306 isolate->heap()->IteratePointers(&visitor); 256 isolate->heap()->IteratePointers(&visitor);
307 delete allocated_set; 257 delete allocated_set;
308 // Only returning a value so that Heap::Validate can be called from an ASSERT. 258 // Only returning a value so that Heap::Validate can be called from an ASSERT.
309 return true; 259 return true;
310 } 260 }
311 261
312 262
313 void Heap::PrintSizes() const { 263 void Heap::PrintSizes() const {
314 OS::PrintErr("New space (%"Pd"k of %"Pd"k) " 264 OS::PrintErr("New space (%"Pd"k of %"Pd"k) "
315 "Old space (%"Pd"k of %"Pd"k) " 265 "Old space (%"Pd"k of %"Pd"k)\n",
316 "Code space (%"Pd"k of %"Pd"k)\n",
317 (new_space_->in_use() / KB), (new_space_->capacity() / KB), 266 (new_space_->in_use() / KB), (new_space_->capacity() / KB),
318 (old_space_->in_use() / KB), (old_space_->capacity() / KB), 267 (old_space_->in_use() / KB), (old_space_->capacity() / KB));
319 (code_space_->in_use() / KB), (code_space_->capacity() / KB));
320 } 268 }
321 269
322 270
323 void Heap::Profile(Dart_HeapProfileWriteCallback callback, void* stream) const { 271 void Heap::Profile(Dart_HeapProfileWriteCallback callback, void* stream) const {
324 HeapProfiler profiler(callback, stream); 272 HeapProfiler profiler(callback, stream);
325 273
326 // Dump the root set. 274 // Dump the root set.
327 HeapProfilerRootVisitor root_visitor(&profiler); 275 HeapProfilerRootVisitor root_visitor(&profiler);
328 Isolate* isolate = Isolate::Current(); 276 Isolate* isolate = Isolate::Current();
329 Isolate* vm_isolate = Dart::vm_isolate(); 277 Isolate* vm_isolate = Dart::vm_isolate();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 isolate()->IncrementNoGCScopeDepth(); 339 isolate()->IncrementNoGCScopeDepth();
392 } 340 }
393 341
394 342
395 NoGCScope::~NoGCScope() { 343 NoGCScope::~NoGCScope() {
396 isolate()->DecrementNoGCScopeDepth(); 344 isolate()->DecrementNoGCScopeDepth();
397 } 345 }
398 #endif // defined(DEBUG) 346 #endif // defined(DEBUG)
399 347
400 } // namespace dart 348 } // namespace dart
OLDNEW
« vm/gc_sweeper.cc ('K') | « vm/heap.h ('k') | vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698