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/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 return old_space_->Contains(addr, HeapPage::kExecutable); | 212 return old_space_->Contains(addr, HeapPage::kExecutable); |
213 } | 213 } |
214 | 214 |
215 | 215 |
216 void Heap::VisitObjects(ObjectVisitor* visitor) const { | 216 void Heap::VisitObjects(ObjectVisitor* visitor) const { |
217 new_space_->VisitObjects(visitor); | 217 new_space_->VisitObjects(visitor); |
218 old_space_->VisitObjects(visitor); | 218 old_space_->VisitObjects(visitor); |
219 } | 219 } |
220 | 220 |
221 | 221 |
| 222 HeapIterationScope::HeapIterationScope() |
| 223 : StackResource(Thread::Current()->isolate()), |
| 224 old_space_(isolate()->heap()->old_space()) { |
| 225 // 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. |
| 227 MonitorLocker ml(old_space_->tasks_lock()); |
| 228 #if defined(DEBUG) |
| 229 // We currently don't support nesting of HeapIterationScopes. |
| 230 ASSERT(!old_space_->is_iterating_); |
| 231 old_space_->is_iterating_ = true; |
| 232 #endif |
| 233 while (old_space_->tasks() > 0) { |
| 234 ml.Wait(); |
| 235 } |
| 236 old_space_->set_tasks(1); |
| 237 } |
| 238 |
| 239 |
| 240 HeapIterationScope::~HeapIterationScope() { |
| 241 MonitorLocker ml(old_space_->tasks_lock()); |
| 242 #if defined(DEBUG) |
| 243 ASSERT(old_space_->is_iterating_); |
| 244 old_space_->is_iterating_ = false; |
| 245 #endif |
| 246 ASSERT(old_space_->tasks() == 1); |
| 247 old_space_->set_tasks(0); |
| 248 ml.Notify(); |
| 249 } |
| 250 |
| 251 |
| 252 void Heap::IterateObjects(ObjectVisitor* visitor) const { |
| 253 // The visitor must not allocate from the heap. |
| 254 NoSafepointScope no_safepoint_scope_; |
| 255 new_space_->VisitObjects(visitor); |
| 256 IterateOldObjects(visitor); |
| 257 } |
| 258 |
| 259 |
| 260 void Heap::IterateOldObjects(ObjectVisitor* visitor) const { |
| 261 HeapIterationScope heap_iteration_scope; |
| 262 old_space_->VisitObjects(visitor); |
| 263 } |
| 264 |
| 265 |
222 void Heap::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 266 void Heap::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
223 new_space_->VisitObjectPointers(visitor); | 267 new_space_->VisitObjectPointers(visitor); |
224 old_space_->VisitObjectPointers(visitor); | 268 old_space_->VisitObjectPointers(visitor); |
225 } | 269 } |
226 | 270 |
227 | 271 |
228 RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const { | 272 RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const { |
229 // Only executable pages can have RawInstructions objects. | 273 // Only executable pages can have RawInstructions objects. |
230 RawObject* raw_obj = old_space_->FindObject(visitor, HeapPage::kExecutable); | 274 RawObject* raw_obj = old_space_->FindObject(visitor, HeapPage::kExecutable); |
231 ASSERT((raw_obj == Object::null()) || | 275 ASSERT((raw_obj == Object::null()) || |
232 (raw_obj->GetClassId() == kInstructionsCid)); | 276 (raw_obj->GetClassId() == kInstructionsCid)); |
233 return reinterpret_cast<RawInstructions*>(raw_obj); | 277 return reinterpret_cast<RawInstructions*>(raw_obj); |
234 } | 278 } |
235 | 279 |
236 | 280 |
237 RawObject* Heap::FindOldObject(FindObjectVisitor* visitor) const { | 281 RawObject* Heap::FindOldObject(FindObjectVisitor* visitor) const { |
238 // Wait for any concurrent GC tasks to finish before walking. | 282 HeapIterationScope heap_iteration_scope; |
239 MonitorLocker ml(old_space_->tasks_lock()); | |
240 while (old_space_->tasks() > 0) { | |
241 ml.Wait(); | |
242 } | |
243 return old_space_->FindObject(visitor, HeapPage::kData); | 283 return old_space_->FindObject(visitor, HeapPage::kData); |
244 } | 284 } |
245 | 285 |
246 | 286 |
247 RawObject* Heap::FindNewObject(FindObjectVisitor* visitor) const { | 287 RawObject* Heap::FindNewObject(FindObjectVisitor* visitor) const { |
248 return new_space_->FindObject(visitor); | 288 return new_space_->FindObject(visitor); |
249 } | 289 } |
250 | 290 |
251 | 291 |
252 RawObject* Heap::FindObject(FindObjectVisitor* visitor) const { | 292 RawObject* Heap::FindObject(FindObjectVisitor* visitor) const { |
253 ASSERT(isolate()->no_safepoint_scope_depth() != 0); | 293 // The visitor must not allocate from the heap. |
| 294 NoSafepointScope no_safepoint_scope; |
254 RawObject* raw_obj = FindNewObject(visitor); | 295 RawObject* raw_obj = FindNewObject(visitor); |
255 if (raw_obj != Object::null()) { | 296 if (raw_obj != Object::null()) { |
256 return raw_obj; | 297 return raw_obj; |
257 } | 298 } |
258 raw_obj = FindOldObject(visitor); | 299 raw_obj = FindOldObject(visitor); |
259 if (raw_obj != Object::null()) { | 300 if (raw_obj != Object::null()) { |
260 return raw_obj; | 301 return raw_obj; |
261 } | 302 } |
262 raw_obj = FindObjectInCodeSpace(visitor); | 303 raw_obj = FindObjectInCodeSpace(visitor); |
263 return raw_obj; | 304 return raw_obj; |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 // VM isolate heap is premarked. | 523 // VM isolate heap is premarked. |
483 VerifyObjectVisitor vm_object_visitor( | 524 VerifyObjectVisitor vm_object_visitor( |
484 isolate(), allocated_set, kRequireMarked); | 525 isolate(), allocated_set, kRequireMarked); |
485 vm_isolate->heap()->VisitObjects(&vm_object_visitor); | 526 vm_isolate->heap()->VisitObjects(&vm_object_visitor); |
486 } | 527 } |
487 return allocated_set; | 528 return allocated_set; |
488 } | 529 } |
489 | 530 |
490 | 531 |
491 bool Heap::Verify(MarkExpectation mark_expectation) const { | 532 bool Heap::Verify(MarkExpectation mark_expectation) const { |
| 533 HeapIterationScope heap_iteration_scope; |
| 534 return VerifyGC(mark_expectation); |
| 535 } |
| 536 |
| 537 |
| 538 bool Heap::VerifyGC(MarkExpectation mark_expectation) const { |
492 ObjectSet* allocated_set = CreateAllocatedObjectSet(mark_expectation); | 539 ObjectSet* allocated_set = CreateAllocatedObjectSet(mark_expectation); |
493 VerifyPointersVisitor visitor(isolate(), allocated_set); | 540 VerifyPointersVisitor visitor(isolate(), allocated_set); |
494 VisitObjectPointers(&visitor); | 541 VisitObjectPointers(&visitor); |
495 delete allocated_set; | 542 delete allocated_set; |
496 // Only returning a value so that Heap::Validate can be called from an ASSERT. | 543 // Only returning a value so that Heap::Validate can be called from an ASSERT. |
497 return true; | 544 return true; |
498 } | 545 } |
499 | 546 |
500 | 547 |
501 void Heap::PrintSizes() const { | 548 void Heap::PrintSizes() const { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 heap->DisableGrowthControl(); | 761 heap->DisableGrowthControl(); |
715 } | 762 } |
716 | 763 |
717 | 764 |
718 NoHeapGrowthControlScope::~NoHeapGrowthControlScope() { | 765 NoHeapGrowthControlScope::~NoHeapGrowthControlScope() { |
719 Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap(); | 766 Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap(); |
720 heap->SetGrowthControlState(current_growth_controller_state_); | 767 heap->SetGrowthControlState(current_growth_controller_state_); |
721 } | 768 } |
722 | 769 |
723 } // namespace dart | 770 } // namespace dart |
OLD | NEW |