| 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 |