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

Side by Side Diff: runtime/vm/heap.cc

Issue 1235433004: VM: Inline Scavenger and PageSpace objects into Heap. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 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
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/isolate.h" 10 #include "vm/isolate.h"
(...skipping 30 matching lines...) Expand all
41 DEFINE_FLAG(bool, verify_before_gc, false, 41 DEFINE_FLAG(bool, verify_before_gc, false,
42 "Enables heap verification before GC."); 42 "Enables heap verification before GC.");
43 DEFINE_FLAG(bool, pretenure_all, false, "Global pretenuring (for testing)."); 43 DEFINE_FLAG(bool, pretenure_all, false, "Global pretenuring (for testing).");
44 44
45 45
46 Heap::Heap(Isolate* isolate, 46 Heap::Heap(Isolate* isolate,
47 intptr_t max_new_gen_semi_words, 47 intptr_t max_new_gen_semi_words,
48 intptr_t max_old_gen_words, 48 intptr_t max_old_gen_words,
49 intptr_t max_external_words) 49 intptr_t max_external_words)
50 : isolate_(isolate), 50 : isolate_(isolate),
51 new_space_(this, max_new_gen_semi_words, kNewObjectAlignmentOffset),
52 old_space_(this, max_old_gen_words, max_external_words),
51 read_only_(false), 53 read_only_(false),
52 gc_in_progress_(false), 54 gc_in_progress_(false),
53 pretenure_policy_(0) { 55 pretenure_policy_(0) {
54 for (int sel = 0; 56 for (int sel = 0;
55 sel < kNumWeakSelectors; 57 sel < kNumWeakSelectors;
56 sel++) { 58 sel++) {
57 new_weak_tables_[sel] = new WeakTable(); 59 new_weak_tables_[sel] = new WeakTable();
58 old_weak_tables_[sel] = new WeakTable(); 60 old_weak_tables_[sel] = new WeakTable();
59 } 61 }
60 new_space_ = new Scavenger(this,
61 max_new_gen_semi_words,
62 kNewObjectAlignmentOffset);
63 old_space_ = new PageSpace(this, max_old_gen_words, max_external_words);
64 stats_.num_ = 0; 62 stats_.num_ = 0;
65 } 63 }
66 64
67 65
68 Heap::~Heap() { 66 Heap::~Heap() {
69 delete new_space_;
70 delete old_space_;
71 for (int sel = 0; 67 for (int sel = 0;
72 sel < kNumWeakSelectors; 68 sel < kNumWeakSelectors;
73 sel++) { 69 sel++) {
74 delete new_weak_tables_[sel]; 70 delete new_weak_tables_[sel];
75 delete old_weak_tables_[sel]; 71 delete old_weak_tables_[sel];
76 } 72 }
77 } 73 }
78 74
79 75
80 uword Heap::AllocateNew(intptr_t size) { 76 uword Heap::AllocateNew(intptr_t size) {
81 ASSERT(isolate()->no_safepoint_scope_depth() == 0); 77 ASSERT(isolate()->no_safepoint_scope_depth() == 0);
82 uword addr = new_space_->TryAllocate(size); 78 uword addr = new_space_.TryAllocate(size);
83 if (addr == 0) { 79 if (addr == 0) {
84 CollectGarbage(kNew); 80 CollectGarbage(kNew);
85 addr = new_space_->TryAllocate(size); 81 addr = new_space_.TryAllocate(size);
86 if (addr == 0) { 82 if (addr == 0) {
87 return AllocateOld(size, HeapPage::kData); 83 return AllocateOld(size, HeapPage::kData);
88 } 84 }
89 } 85 }
90 return addr; 86 return addr;
91 } 87 }
92 88
93 89
94 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) { 90 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) {
95 ASSERT(isolate()->no_safepoint_scope_depth() == 0); 91 ASSERT(isolate()->no_safepoint_scope_depth() == 0);
96 uword addr = old_space_->TryAllocate(size, type); 92 uword addr = old_space_.TryAllocate(size, type);
97 if (addr != 0) { 93 if (addr != 0) {
98 return addr; 94 return addr;
99 } 95 }
100 // If we are in the process of running a sweep wait for the sweeper to free 96 // If we are in the process of running a sweep wait for the sweeper to free
101 // memory. 97 // memory.
102 { 98 {
103 MonitorLocker ml(old_space_->tasks_lock()); 99 MonitorLocker ml(old_space_.tasks_lock());
104 addr = old_space_->TryAllocate(size, type); 100 addr = old_space_.TryAllocate(size, type);
105 while ((addr == 0) && (old_space_->tasks() > 0)) { 101 while ((addr == 0) && (old_space_.tasks() > 0)) {
106 ml.Wait(); 102 ml.Wait();
107 addr = old_space_->TryAllocate(size, type); 103 addr = old_space_.TryAllocate(size, type);
108 } 104 }
109 } 105 }
110 if (addr != 0) { 106 if (addr != 0) {
111 return addr; 107 return addr;
112 } 108 }
113 // All GC tasks finished without allocating successfully. Run a full GC. 109 // All GC tasks finished without allocating successfully. Run a full GC.
114 CollectAllGarbage(); 110 CollectAllGarbage();
115 addr = old_space_->TryAllocate(size, type); 111 addr = old_space_.TryAllocate(size, type);
116 if (addr != 0) { 112 if (addr != 0) {
117 return addr; 113 return addr;
118 } 114 }
119 // Wait for all of the concurrent tasks to finish before giving up. 115 // Wait for all of the concurrent tasks to finish before giving up.
120 { 116 {
121 MonitorLocker ml(old_space_->tasks_lock()); 117 MonitorLocker ml(old_space_.tasks_lock());
122 addr = old_space_->TryAllocate(size, type); 118 addr = old_space_.TryAllocate(size, type);
123 while ((addr == 0) && (old_space_->tasks() > 0)) { 119 while ((addr == 0) && (old_space_.tasks() > 0)) {
124 ml.Wait(); 120 ml.Wait();
125 addr = old_space_->TryAllocate(size, type); 121 addr = old_space_.TryAllocate(size, type);
126 } 122 }
127 } 123 }
128 if (addr != 0) { 124 if (addr != 0) {
129 return addr; 125 return addr;
130 } 126 }
131 // Force growth before attempting a synchronous GC. 127 // Force growth before attempting a synchronous GC.
132 addr = old_space_->TryAllocate(size, type, PageSpace::kForceGrowth); 128 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
133 if (addr != 0) { 129 if (addr != 0) {
134 return addr; 130 return addr;
135 } 131 }
136 // Before throwing an out-of-memory error try a synchronous GC. 132 // Before throwing an out-of-memory error try a synchronous GC.
137 CollectAllGarbage(); 133 CollectAllGarbage();
138 { 134 {
139 MonitorLocker ml(old_space_->tasks_lock()); 135 MonitorLocker ml(old_space_.tasks_lock());
140 while (old_space_->tasks() > 0) { 136 while (old_space_.tasks() > 0) {
141 ml.Wait(); 137 ml.Wait();
142 } 138 }
143 } 139 }
144 addr = old_space_->TryAllocate(size, type, PageSpace::kForceGrowth); 140 addr = old_space_.TryAllocate(size, type, PageSpace::kForceGrowth);
145 if (addr != 0) { 141 if (addr != 0) {
146 return addr; 142 return addr;
147 } 143 }
148 // Give up allocating this object. 144 // Give up allocating this object.
149 OS::PrintErr( 145 OS::PrintErr(
150 "Exhausted heap space, trying to allocate %" Pd " bytes.\n", size); 146 "Exhausted heap space, trying to allocate %" Pd " bytes.\n", size);
151 return 0; 147 return 0;
152 } 148 }
153 149
154 150
155 uword Heap::AllocatePretenured(intptr_t size) { 151 uword Heap::AllocatePretenured(intptr_t size) {
156 ASSERT(isolate()->no_safepoint_scope_depth() == 0); 152 ASSERT(isolate()->no_safepoint_scope_depth() == 0);
157 uword addr = old_space_->TryAllocateDataBump(size, PageSpace::kControlGrowth); 153 uword addr = old_space_.TryAllocateDataBump(size, PageSpace::kControlGrowth);
158 if (addr != 0) return addr; 154 if (addr != 0) return addr;
159 return AllocateOld(size, HeapPage::kData); 155 return AllocateOld(size, HeapPage::kData);
160 } 156 }
161 157
162 158
163 void Heap::AllocateExternal(intptr_t size, Space space) { 159 void Heap::AllocateExternal(intptr_t size, Space space) {
164 ASSERT(isolate()->no_safepoint_scope_depth() == 0); 160 ASSERT(isolate()->no_safepoint_scope_depth() == 0);
165 if (space == kNew) { 161 if (space == kNew) {
166 new_space_->AllocateExternal(size); 162 new_space_.AllocateExternal(size);
167 if (new_space_->ExternalInWords() > (FLAG_new_gen_ext_limit * MBInWords)) { 163 if (new_space_.ExternalInWords() > (FLAG_new_gen_ext_limit * MBInWords)) {
168 // Attempt to free some external allocation by a scavenge. (If the total 164 // Attempt to free some external allocation by a scavenge. (If the total
169 // remains above the limit, next external alloc will trigger another.) 165 // remains above the limit, next external alloc will trigger another.)
170 CollectGarbage(kNew); 166 CollectGarbage(kNew);
171 } 167 }
172 } else { 168 } else {
173 ASSERT(space == kOld); 169 ASSERT(space == kOld);
174 old_space_->AllocateExternal(size); 170 old_space_.AllocateExternal(size);
175 if (old_space_->NeedsGarbageCollection()) { 171 if (old_space_.NeedsGarbageCollection()) {
176 CollectAllGarbage(); 172 CollectAllGarbage();
177 } 173 }
178 } 174 }
179 } 175 }
180 176
181 void Heap::FreeExternal(intptr_t size, Space space) { 177 void Heap::FreeExternal(intptr_t size, Space space) {
182 if (space == kNew) { 178 if (space == kNew) {
183 new_space_->FreeExternal(size); 179 new_space_.FreeExternal(size);
184 } else { 180 } else {
185 ASSERT(space == kOld); 181 ASSERT(space == kOld);
186 old_space_->FreeExternal(size); 182 old_space_.FreeExternal(size);
187 } 183 }
188 } 184 }
189 185
190 void Heap::PromoteExternal(intptr_t size) { 186 void Heap::PromoteExternal(intptr_t size) {
191 new_space_->FreeExternal(size); 187 new_space_.FreeExternal(size);
192 old_space_->AllocateExternal(size); 188 old_space_.AllocateExternal(size);
193 } 189 }
194 190
195 bool Heap::Contains(uword addr) const { 191 bool Heap::Contains(uword addr) const {
196 return new_space_->Contains(addr) || 192 return new_space_.Contains(addr) ||
197 old_space_->Contains(addr); 193 old_space_.Contains(addr);
198 } 194 }
199 195
200 196
201 bool Heap::NewContains(uword addr) const { 197 bool Heap::NewContains(uword addr) const {
202 return new_space_->Contains(addr); 198 return new_space_.Contains(addr);
203 } 199 }
204 200
205 201
206 bool Heap::OldContains(uword addr) const { 202 bool Heap::OldContains(uword addr) const {
207 return old_space_->Contains(addr); 203 return old_space_.Contains(addr);
208 } 204 }
209 205
210 206
211 bool Heap::CodeContains(uword addr) const { 207 bool Heap::CodeContains(uword addr) const {
212 return old_space_->Contains(addr, HeapPage::kExecutable); 208 return old_space_.Contains(addr, HeapPage::kExecutable);
213 } 209 }
214 210
215 211
216 void Heap::VisitObjects(ObjectVisitor* visitor) const { 212 void Heap::VisitObjects(ObjectVisitor* visitor) const {
217 new_space_->VisitObjects(visitor); 213 new_space_.VisitObjects(visitor);
218 old_space_->VisitObjects(visitor); 214 old_space_.VisitObjects(visitor);
219 } 215 }
220 216
221 217
222 HeapIterationScope::HeapIterationScope() 218 HeapIterationScope::HeapIterationScope()
223 : StackResource(Thread::Current()->isolate()), 219 : StackResource(Thread::Current()->isolate()),
224 old_space_(isolate()->heap()->old_space()) { 220 old_space_(isolate()->heap()->old_space()) {
225 // It's not yet safe to iterate over a paged space while it's concurrently 221 // It's not yet safe to iterate over a paged space while it's concurrently
226 // sweeping, so wait for any such task to complete first. 222 // sweeping, so wait for any such task to complete first.
227 MonitorLocker ml(old_space_->tasks_lock()); 223 MonitorLocker ml(old_space_->tasks_lock());
228 #if defined(DEBUG) 224 #if defined(DEBUG)
(...skipping 16 matching lines...) Expand all
245 #endif 241 #endif
246 ASSERT(old_space_->tasks() == 1); 242 ASSERT(old_space_->tasks() == 1);
247 old_space_->set_tasks(0); 243 old_space_->set_tasks(0);
248 ml.Notify(); 244 ml.Notify();
249 } 245 }
250 246
251 247
252 void Heap::IterateObjects(ObjectVisitor* visitor) const { 248 void Heap::IterateObjects(ObjectVisitor* visitor) const {
253 // The visitor must not allocate from the heap. 249 // The visitor must not allocate from the heap.
254 NoSafepointScope no_safepoint_scope_; 250 NoSafepointScope no_safepoint_scope_;
255 new_space_->VisitObjects(visitor); 251 new_space_.VisitObjects(visitor);
256 IterateOldObjects(visitor); 252 IterateOldObjects(visitor);
257 } 253 }
258 254
259 255
260 void Heap::IterateOldObjects(ObjectVisitor* visitor) const { 256 void Heap::IterateOldObjects(ObjectVisitor* visitor) const {
261 HeapIterationScope heap_iteration_scope; 257 HeapIterationScope heap_iteration_scope;
262 old_space_->VisitObjects(visitor); 258 old_space_.VisitObjects(visitor);
263 } 259 }
264 260
265 261
266 void Heap::VisitObjectPointers(ObjectPointerVisitor* visitor) const { 262 void Heap::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
267 new_space_->VisitObjectPointers(visitor); 263 new_space_.VisitObjectPointers(visitor);
268 old_space_->VisitObjectPointers(visitor); 264 old_space_.VisitObjectPointers(visitor);
269 } 265 }
270 266
271 267
272 RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const { 268 RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const {
273 // Only executable pages can have RawInstructions objects. 269 // Only executable pages can have RawInstructions objects.
274 RawObject* raw_obj = old_space_->FindObject(visitor, HeapPage::kExecutable); 270 RawObject* raw_obj = old_space_.FindObject(visitor, HeapPage::kExecutable);
275 ASSERT((raw_obj == Object::null()) || 271 ASSERT((raw_obj == Object::null()) ||
276 (raw_obj->GetClassId() == kInstructionsCid)); 272 (raw_obj->GetClassId() == kInstructionsCid));
277 return reinterpret_cast<RawInstructions*>(raw_obj); 273 return reinterpret_cast<RawInstructions*>(raw_obj);
278 } 274 }
279 275
280 276
281 RawObject* Heap::FindOldObject(FindObjectVisitor* visitor) const { 277 RawObject* Heap::FindOldObject(FindObjectVisitor* visitor) const {
282 HeapIterationScope heap_iteration_scope; 278 HeapIterationScope heap_iteration_scope;
283 return old_space_->FindObject(visitor, HeapPage::kData); 279 return old_space_.FindObject(visitor, HeapPage::kData);
284 } 280 }
285 281
286 282
287 RawObject* Heap::FindNewObject(FindObjectVisitor* visitor) const { 283 RawObject* Heap::FindNewObject(FindObjectVisitor* visitor) const {
288 return new_space_->FindObject(visitor); 284 return new_space_.FindObject(visitor);
289 } 285 }
290 286
291 287
292 RawObject* Heap::FindObject(FindObjectVisitor* visitor) const { 288 RawObject* Heap::FindObject(FindObjectVisitor* visitor) const {
293 // The visitor must not allocate from the heap. 289 // The visitor must not allocate from the heap.
294 NoSafepointScope no_safepoint_scope; 290 NoSafepointScope no_safepoint_scope;
295 RawObject* raw_obj = FindNewObject(visitor); 291 RawObject* raw_obj = FindNewObject(visitor);
296 if (raw_obj != Object::null()) { 292 if (raw_obj != Object::null()) {
297 return raw_obj; 293 return raw_obj;
298 } 294 }
(...skipping 12 matching lines...) Expand all
311 TIMERSCOPE(isolate(), time_gc); 307 TIMERSCOPE(isolate(), time_gc);
312 bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks); 308 bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
313 switch (space) { 309 switch (space) {
314 case kNew: { 310 case kNew: {
315 VMTagScope tagScope(isolate(), VMTag::kGCNewSpaceTagId); 311 VMTagScope tagScope(isolate(), VMTag::kGCNewSpaceTagId);
316 TimelineDurationScope tds(isolate(), 312 TimelineDurationScope tds(isolate(),
317 isolate()->GetGCStream(), 313 isolate()->GetGCStream(),
318 "CollectNewGeneration"); 314 "CollectNewGeneration");
319 RecordBeforeGC(kNew, reason); 315 RecordBeforeGC(kNew, reason);
320 UpdateClassHeapStatsBeforeGC(kNew); 316 UpdateClassHeapStatsBeforeGC(kNew);
321 new_space_->Scavenge(invoke_api_callbacks); 317 new_space_.Scavenge(invoke_api_callbacks);
322 isolate()->class_table()->UpdatePromoted(); 318 isolate()->class_table()->UpdatePromoted();
323 UpdatePretenurePolicy(); 319 UpdatePretenurePolicy();
324 RecordAfterGC(); 320 RecordAfterGC();
325 PrintStats(); 321 PrintStats();
326 if (old_space_->NeedsGarbageCollection()) { 322 if (old_space_.NeedsGarbageCollection()) {
327 // Old collections should call the API callbacks. 323 // Old collections should call the API callbacks.
328 CollectGarbage(kOld, kInvokeApiCallbacks, kPromotion); 324 CollectGarbage(kOld, kInvokeApiCallbacks, kPromotion);
329 } 325 }
330 break; 326 break;
331 } 327 }
332 case kOld: 328 case kOld:
333 case kCode: { 329 case kCode: {
334 VMTagScope tagScope(isolate(), VMTag::kGCOldSpaceTagId); 330 VMTagScope tagScope(isolate(), VMTag::kGCOldSpaceTagId);
335 TimelineDurationScope tds(isolate(), 331 TimelineDurationScope tds(isolate(),
336 isolate()->GetGCStream(), 332 isolate()->GetGCStream(),
337 "CollectOldGeneration"); 333 "CollectOldGeneration");
338 RecordBeforeGC(kOld, reason); 334 RecordBeforeGC(kOld, reason);
339 UpdateClassHeapStatsBeforeGC(kOld); 335 UpdateClassHeapStatsBeforeGC(kOld);
340 old_space_->MarkSweep(invoke_api_callbacks); 336 old_space_.MarkSweep(invoke_api_callbacks);
341 RecordAfterGC(); 337 RecordAfterGC();
342 PrintStats(); 338 PrintStats();
343 break; 339 break;
344 } 340 }
345 default: 341 default:
346 UNREACHABLE(); 342 UNREACHABLE();
347 } 343 }
348 } 344 }
349 345
350 346
(...skipping 19 matching lines...) Expand all
370 366
371 void Heap::CollectAllGarbage() { 367 void Heap::CollectAllGarbage() {
372 TIMERSCOPE(isolate(), time_gc); 368 TIMERSCOPE(isolate(), time_gc);
373 { 369 {
374 VMTagScope tagScope(isolate(), VMTag::kGCNewSpaceTagId); 370 VMTagScope tagScope(isolate(), VMTag::kGCNewSpaceTagId);
375 TimelineDurationScope tds(isolate(), 371 TimelineDurationScope tds(isolate(),
376 isolate()->GetGCStream(), 372 isolate()->GetGCStream(),
377 "CollectNewGeneration"); 373 "CollectNewGeneration");
378 RecordBeforeGC(kNew, kFull); 374 RecordBeforeGC(kNew, kFull);
379 UpdateClassHeapStatsBeforeGC(kNew); 375 UpdateClassHeapStatsBeforeGC(kNew);
380 new_space_->Scavenge(kInvokeApiCallbacks); 376 new_space_.Scavenge(kInvokeApiCallbacks);
381 isolate()->class_table()->UpdatePromoted(); 377 isolate()->class_table()->UpdatePromoted();
382 UpdatePretenurePolicy(); 378 UpdatePretenurePolicy();
383 RecordAfterGC(); 379 RecordAfterGC();
384 PrintStats(); 380 PrintStats();
385 } 381 }
386 { 382 {
387 VMTagScope tagScope(isolate(), VMTag::kGCOldSpaceTagId); 383 VMTagScope tagScope(isolate(), VMTag::kGCOldSpaceTagId);
388 TimelineDurationScope tds(isolate(), 384 TimelineDurationScope tds(isolate(),
389 isolate()->GetGCStream(), 385 isolate()->GetGCStream(),
390 "CollectOldGeneration"); 386 "CollectOldGeneration");
391 RecordBeforeGC(kOld, kFull); 387 RecordBeforeGC(kOld, kFull);
392 UpdateClassHeapStatsBeforeGC(kOld); 388 UpdateClassHeapStatsBeforeGC(kOld);
393 old_space_->MarkSweep(kInvokeApiCallbacks); 389 old_space_.MarkSweep(kInvokeApiCallbacks);
394 RecordAfterGC(); 390 RecordAfterGC();
395 PrintStats(); 391 PrintStats();
396 } 392 }
397 } 393 }
398 394
399 395
400 bool Heap::ShouldPretenure(intptr_t class_id) const { 396 bool Heap::ShouldPretenure(intptr_t class_id) const {
401 if (class_id == kOneByteStringCid) { 397 if (class_id == kOneByteStringCid) {
402 return pretenure_policy_ > 0; 398 return pretenure_policy_ > 0;
403 } else { 399 } else {
(...skipping 21 matching lines...) Expand all
425 (100 * stats->promoted_count) / allocated; 421 (100 * stats->promoted_count) / allocated;
426 if (promo_percent >= FLAG_pretenure_threshold) { 422 if (promo_percent >= FLAG_pretenure_threshold) {
427 pretenure_policy_ += FLAG_pretenure_interval; 423 pretenure_policy_ += FLAG_pretenure_interval;
428 } else { 424 } else {
429 pretenure_policy_ = Utils::Maximum(0, pretenure_policy_ - 1); 425 pretenure_policy_ = Utils::Maximum(0, pretenure_policy_ - 1);
430 } 426 }
431 } 427 }
432 428
433 429
434 void Heap::SetGrowthControlState(bool state) { 430 void Heap::SetGrowthControlState(bool state) {
435 old_space_->SetGrowthControlState(state); 431 old_space_.SetGrowthControlState(state);
436 } 432 }
437 433
438 434
439 bool Heap::GrowthControlState() { 435 bool Heap::GrowthControlState() {
440 return old_space_->GrowthControlState(); 436 return old_space_.GrowthControlState();
441 } 437 }
442 438
443 439
444 void Heap::WriteProtect(bool read_only) { 440 void Heap::WriteProtect(bool read_only) {
445 read_only_ = read_only; 441 read_only_ = read_only;
446 new_space_->WriteProtect(read_only); 442 new_space_.WriteProtect(read_only);
447 old_space_->WriteProtect(read_only); 443 old_space_.WriteProtect(read_only);
448 } 444 }
449 445
450 446
451 uword Heap::TopAddress(Heap::Space space) { 447 uword Heap::TopAddress(Heap::Space space) {
452 if (space == kNew) { 448 if (space == kNew) {
453 return reinterpret_cast<uword>(new_space_->TopAddress()); 449 return reinterpret_cast<uword>(new_space_.TopAddress());
454 } else { 450 } else {
455 ASSERT(space == kPretenured); 451 ASSERT(space == kPretenured);
456 return reinterpret_cast<uword>(old_space_->TopAddress()); 452 return reinterpret_cast<uword>(old_space_.TopAddress());
457 } 453 }
458 } 454 }
459 455
460 456
461 uword Heap::EndAddress(Heap::Space space) { 457 uword Heap::EndAddress(Heap::Space space) {
462 if (space == kNew) { 458 if (space == kNew) {
463 return reinterpret_cast<uword>(new_space_->EndAddress()); 459 return reinterpret_cast<uword>(new_space_.EndAddress());
464 } else { 460 } else {
465 ASSERT(space == kPretenured); 461 ASSERT(space == kPretenured);
466 return reinterpret_cast<uword>(old_space_->EndAddress()); 462 return reinterpret_cast<uword>(old_space_.EndAddress());
467 } 463 }
468 } 464 }
469 465
470 466
471 Heap::Space Heap::SpaceForAllocation(intptr_t cid) const { 467 Heap::Space Heap::SpaceForAllocation(intptr_t cid) const {
472 return FLAG_pretenure_all ? kPretenured : kNew; 468 return FLAG_pretenure_all ? kPretenured : kNew;
473 } 469 }
474 470
475 471
476 void Heap::Init(Isolate* isolate, 472 void Heap::Init(Isolate* isolate,
477 intptr_t max_new_gen_words, 473 intptr_t max_new_gen_words,
478 intptr_t max_old_gen_words, 474 intptr_t max_old_gen_words,
479 intptr_t max_external_words) { 475 intptr_t max_external_words) {
480 ASSERT(isolate->heap() == NULL); 476 ASSERT(isolate->heap() == NULL);
481 Heap* heap = new Heap(isolate, 477 Heap* heap = new Heap(isolate,
482 max_new_gen_words, 478 max_new_gen_words,
483 max_old_gen_words, 479 max_old_gen_words,
484 max_external_words); 480 max_external_words);
485 isolate->set_heap(heap); 481 isolate->set_heap(heap);
486 } 482 }
487 483
488 484
489 void Heap::GetMergedAddressRange(uword* start, uword* end) const { 485 void Heap::GetMergedAddressRange(uword* start, uword* end) const {
490 if (new_space_->CapacityInWords() != 0) { 486 if (new_space_.CapacityInWords() != 0) {
491 uword new_start; 487 uword new_start;
492 uword new_end; 488 uword new_end;
493 new_space_->StartEndAddress(&new_start, &new_end); 489 new_space_.StartEndAddress(&new_start, &new_end);
494 *start = Utils::Minimum(new_start, *start); 490 *start = Utils::Minimum(new_start, *start);
495 *end = Utils::Maximum(new_end, *end); 491 *end = Utils::Maximum(new_end, *end);
496 } 492 }
497 if (old_space_->CapacityInWords() != 0) { 493 if (old_space_.CapacityInWords() != 0) {
498 uword old_start; 494 uword old_start;
499 uword old_end; 495 uword old_end;
500 old_space_->StartEndAddress(&old_start, &old_end); 496 old_space_.StartEndAddress(&old_start, &old_end);
501 *start = Utils::Minimum(old_start, *start); 497 *start = Utils::Minimum(old_start, *start);
502 *end = Utils::Maximum(old_end, *end); 498 *end = Utils::Maximum(old_end, *end);
503 } 499 }
504 ASSERT(*start <= *end); 500 ASSERT(*start <= *end);
505 } 501 }
506 502
507 503
508 ObjectSet* Heap::CreateAllocatedObjectSet( 504 ObjectSet* Heap::CreateAllocatedObjectSet(
509 MarkExpectation mark_expectation) const { 505 MarkExpectation mark_expectation) const {
510 uword start = static_cast<uword>(-1); 506 uword start = static_cast<uword>(-1);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 OS::PrintErr("New space (%" Pd "k of %" Pd "k) " 545 OS::PrintErr("New space (%" Pd "k of %" Pd "k) "
550 "Old space (%" Pd "k of %" Pd "k)\n", 546 "Old space (%" Pd "k of %" Pd "k)\n",
551 (UsedInWords(kNew) / KBInWords), 547 (UsedInWords(kNew) / KBInWords),
552 (CapacityInWords(kNew) / KBInWords), 548 (CapacityInWords(kNew) / KBInWords),
553 (UsedInWords(kOld) / KBInWords), 549 (UsedInWords(kOld) / KBInWords),
554 (CapacityInWords(kOld) / KBInWords)); 550 (CapacityInWords(kOld) / KBInWords));
555 } 551 }
556 552
557 553
558 intptr_t Heap::UsedInWords(Space space) const { 554 intptr_t Heap::UsedInWords(Space space) const {
559 return space == kNew ? new_space_->UsedInWords() : old_space_->UsedInWords(); 555 return space == kNew ? new_space_.UsedInWords() : old_space_.UsedInWords();
560 } 556 }
561 557
562 558
563 intptr_t Heap::CapacityInWords(Space space) const { 559 intptr_t Heap::CapacityInWords(Space space) const {
564 return space == kNew ? new_space_->CapacityInWords() : 560 return space == kNew ? new_space_.CapacityInWords() :
565 old_space_->CapacityInWords(); 561 old_space_.CapacityInWords();
566 } 562 }
567 563
568 intptr_t Heap::ExternalInWords(Space space) const { 564 intptr_t Heap::ExternalInWords(Space space) const {
569 return space == kNew ? new_space_->ExternalInWords() : 565 return space == kNew ? new_space_.ExternalInWords() :
570 old_space_->ExternalInWords(); 566 old_space_.ExternalInWords();
571 } 567 }
572 568
573 int64_t Heap::GCTimeInMicros(Space space) const { 569 int64_t Heap::GCTimeInMicros(Space space) const {
574 if (space == kNew) { 570 if (space == kNew) {
575 return new_space_->gc_time_micros(); 571 return new_space_.gc_time_micros();
576 } 572 }
577 return old_space_->gc_time_micros(); 573 return old_space_.gc_time_micros();
578 } 574 }
579 575
580 576
581 intptr_t Heap::Collections(Space space) const { 577 intptr_t Heap::Collections(Space space) const {
582 if (space == kNew) { 578 if (space == kNew) {
583 return new_space_->collections(); 579 return new_space_.collections();
584 } 580 }
585 return old_space_->collections(); 581 return old_space_.collections();
586 } 582 }
587 583
588 584
589 const char* Heap::GCReasonToString(GCReason gc_reason) { 585 const char* Heap::GCReasonToString(GCReason gc_reason) {
590 switch (gc_reason) { 586 switch (gc_reason) {
591 case kNewSpace: 587 case kNewSpace:
592 return "new space"; 588 return "new space";
593 case kPromotion: 589 case kPromotion:
594 return "promotion"; 590 return "promotion";
595 case kOldSpace: 591 case kOldSpace:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 new_weak_tables_[sel]->SetValue(raw_obj, val); 628 new_weak_tables_[sel]->SetValue(raw_obj, val);
633 } else { 629 } else {
634 ASSERT(raw_obj->IsOldObject()); 630 ASSERT(raw_obj->IsOldObject());
635 old_weak_tables_[sel]->SetValue(raw_obj, val); 631 old_weak_tables_[sel]->SetValue(raw_obj, val);
636 } 632 }
637 } 633 }
638 634
639 635
640 void Heap::PrintToJSONObject(Space space, JSONObject* object) const { 636 void Heap::PrintToJSONObject(Space space, JSONObject* object) const {
641 if (space == kNew) { 637 if (space == kNew) {
642 new_space_->PrintToJSONObject(object); 638 new_space_.PrintToJSONObject(object);
643 } else { 639 } else {
644 old_space_->PrintToJSONObject(object); 640 old_space_.PrintToJSONObject(object);
645 } 641 }
646 } 642 }
647 643
648 644
649 void Heap::RecordBeforeGC(Space space, GCReason reason) { 645 void Heap::RecordBeforeGC(Space space, GCReason reason) {
650 ASSERT(!gc_in_progress_); 646 ASSERT(!gc_in_progress_);
651 gc_in_progress_ = true; 647 gc_in_progress_ = true;
652 stats_.num_++; 648 stats_.num_++;
653 stats_.space_ = space; 649 stats_.space_ = space;
654 stats_.reason_ = reason; 650 stats_.reason_ = reason;
655 stats_.before_.micros_ = OS::GetCurrentTimeMicros(); 651 stats_.before_.micros_ = OS::GetCurrentTimeMicros();
656 stats_.before_.new_ = new_space_->GetCurrentUsage(); 652 stats_.before_.new_ = new_space_.GetCurrentUsage();
657 stats_.before_.old_ = old_space_->GetCurrentUsage(); 653 stats_.before_.old_ = old_space_.GetCurrentUsage();
658 stats_.times_[0] = 0; 654 stats_.times_[0] = 0;
659 stats_.times_[1] = 0; 655 stats_.times_[1] = 0;
660 stats_.times_[2] = 0; 656 stats_.times_[2] = 0;
661 stats_.times_[3] = 0; 657 stats_.times_[3] = 0;
662 stats_.data_[0] = 0; 658 stats_.data_[0] = 0;
663 stats_.data_[1] = 0; 659 stats_.data_[1] = 0;
664 stats_.data_[2] = 0; 660 stats_.data_[2] = 0;
665 stats_.data_[3] = 0; 661 stats_.data_[3] = 0;
666 } 662 }
667 663
668 664
669 void Heap::RecordAfterGC() { 665 void Heap::RecordAfterGC() {
670 stats_.after_.micros_ = OS::GetCurrentTimeMicros(); 666 stats_.after_.micros_ = OS::GetCurrentTimeMicros();
671 int64_t delta = stats_.after_.micros_ - stats_.before_.micros_; 667 int64_t delta = stats_.after_.micros_ - stats_.before_.micros_;
672 if (stats_.space_ == kNew) { 668 if (stats_.space_ == kNew) {
673 new_space_->AddGCTime(delta); 669 new_space_.AddGCTime(delta);
674 new_space_->IncrementCollections(); 670 new_space_.IncrementCollections();
675 } else { 671 } else {
676 old_space_->AddGCTime(delta); 672 old_space_.AddGCTime(delta);
677 old_space_->IncrementCollections(); 673 old_space_.IncrementCollections();
678 } 674 }
679 stats_.after_.new_ = new_space_->GetCurrentUsage(); 675 stats_.after_.new_ = new_space_.GetCurrentUsage();
680 stats_.after_.old_ = old_space_->GetCurrentUsage(); 676 stats_.after_.old_ = old_space_.GetCurrentUsage();
681 ASSERT(gc_in_progress_); 677 ASSERT(gc_in_progress_);
682 gc_in_progress_ = false; 678 gc_in_progress_ = false;
683 if (Service::gc_stream.enabled()) { 679 if (Service::gc_stream.enabled()) {
684 ServiceEvent event(Isolate::Current(), ServiceEvent::kGC); 680 ServiceEvent event(Isolate::Current(), ServiceEvent::kGC);
685 event.set_gc_stats(&stats_); 681 event.set_gc_stats(&stats_);
686 Service::HandleEvent(&event); 682 Service::HandleEvent(&event);
687 } 683 }
688 } 684 }
689 685
690 686
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 heap->DisableGrowthControl(); 757 heap->DisableGrowthControl();
762 } 758 }
763 759
764 760
765 NoHeapGrowthControlScope::~NoHeapGrowthControlScope() { 761 NoHeapGrowthControlScope::~NoHeapGrowthControlScope() {
766 Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap(); 762 Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap();
767 heap->SetGrowthControlState(current_growth_controller_state_); 763 heap->SetGrowthControlState(current_growth_controller_state_);
768 } 764 }
769 765
770 } // namespace dart 766 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/heap.h ('k') | runtime/vm/pages.h » ('j') | runtime/vm/pages.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698