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 while (old_space_->tasks() > 0) { | |
229 ml.Wait(); | |
230 } | |
231 old_space_->set_tasks(1); | |
siva
2015/07/07 18:10:24
How do we ensure that people don't end up with nes
koda
2015/07/07 22:46:39
Done.
| |
232 } | |
233 | |
234 | |
235 HeapIterationScope::~HeapIterationScope() { | |
236 old_space_->set_tasks(0); | |
siva
2015/07/07 18:10:24
Doesn't this need to be set under a lock as well?
koda
2015/07/07 22:46:39
Done.
| |
237 } | |
238 | |
239 | |
240 void Heap::IterateObjects(ObjectVisitor* visitor) const { | |
241 // The visitor must not allocate from the heap. | |
242 NoSafepointScope no_safepoint_scope_; | |
243 new_space_->VisitObjects(visitor); | |
244 IterateOldObjects(visitor); | |
245 } | |
246 | |
247 | |
248 void Heap::IterateOldObjects(ObjectVisitor* visitor) const { | |
249 HeapIterationScope heap_iteration_scope; | |
250 old_space_->VisitObjects(visitor); | |
251 } | |
252 | |
253 | |
222 void Heap::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 254 void Heap::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
223 new_space_->VisitObjectPointers(visitor); | 255 new_space_->VisitObjectPointers(visitor); |
224 old_space_->VisitObjectPointers(visitor); | 256 old_space_->VisitObjectPointers(visitor); |
225 } | 257 } |
226 | 258 |
227 | 259 |
228 RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const { | 260 RawInstructions* Heap::FindObjectInCodeSpace(FindObjectVisitor* visitor) const { |
229 // Only executable pages can have RawInstructions objects. | 261 // Only executable pages can have RawInstructions objects. |
230 RawObject* raw_obj = old_space_->FindObject(visitor, HeapPage::kExecutable); | 262 RawObject* raw_obj = old_space_->FindObject(visitor, HeapPage::kExecutable); |
231 ASSERT((raw_obj == Object::null()) || | 263 ASSERT((raw_obj == Object::null()) || |
232 (raw_obj->GetClassId() == kInstructionsCid)); | 264 (raw_obj->GetClassId() == kInstructionsCid)); |
233 return reinterpret_cast<RawInstructions*>(raw_obj); | 265 return reinterpret_cast<RawInstructions*>(raw_obj); |
234 } | 266 } |
235 | 267 |
236 | 268 |
237 RawObject* Heap::FindOldObject(FindObjectVisitor* visitor) const { | 269 RawObject* Heap::FindOldObject(FindObjectVisitor* visitor) const { |
238 // Wait for any concurrent GC tasks to finish before walking. | 270 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); | 271 return old_space_->FindObject(visitor, HeapPage::kData); |
244 } | 272 } |
245 | 273 |
246 | 274 |
247 RawObject* Heap::FindNewObject(FindObjectVisitor* visitor) const { | 275 RawObject* Heap::FindNewObject(FindObjectVisitor* visitor) const { |
248 return new_space_->FindObject(visitor); | 276 return new_space_->FindObject(visitor); |
249 } | 277 } |
250 | 278 |
251 | 279 |
252 RawObject* Heap::FindObject(FindObjectVisitor* visitor) const { | 280 RawObject* Heap::FindObject(FindObjectVisitor* visitor) const { |
253 ASSERT(isolate()->no_safepoint_scope_depth() != 0); | 281 // The visitor must not allocate from the heap. |
282 NoSafepointScope no_safepoint_scope; | |
254 RawObject* raw_obj = FindNewObject(visitor); | 283 RawObject* raw_obj = FindNewObject(visitor); |
255 if (raw_obj != Object::null()) { | 284 if (raw_obj != Object::null()) { |
256 return raw_obj; | 285 return raw_obj; |
257 } | 286 } |
258 raw_obj = FindOldObject(visitor); | 287 raw_obj = FindOldObject(visitor); |
259 if (raw_obj != Object::null()) { | 288 if (raw_obj != Object::null()) { |
260 return raw_obj; | 289 return raw_obj; |
261 } | 290 } |
262 raw_obj = FindObjectInCodeSpace(visitor); | 291 raw_obj = FindObjectInCodeSpace(visitor); |
263 return raw_obj; | 292 return raw_obj; |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
482 // VM isolate heap is premarked. | 511 // VM isolate heap is premarked. |
483 VerifyObjectVisitor vm_object_visitor( | 512 VerifyObjectVisitor vm_object_visitor( |
484 isolate(), allocated_set, kRequireMarked); | 513 isolate(), allocated_set, kRequireMarked); |
485 vm_isolate->heap()->VisitObjects(&vm_object_visitor); | 514 vm_isolate->heap()->VisitObjects(&vm_object_visitor); |
486 } | 515 } |
487 return allocated_set; | 516 return allocated_set; |
488 } | 517 } |
489 | 518 |
490 | 519 |
491 bool Heap::Verify(MarkExpectation mark_expectation) const { | 520 bool Heap::Verify(MarkExpectation mark_expectation) const { |
521 HeapIterationScope heap_iteration_scope; | |
522 return VerifyGC(mark_expectation); | |
523 } | |
524 | |
525 | |
526 bool Heap::VerifyGC(MarkExpectation mark_expectation) const { | |
492 ObjectSet* allocated_set = CreateAllocatedObjectSet(mark_expectation); | 527 ObjectSet* allocated_set = CreateAllocatedObjectSet(mark_expectation); |
493 VerifyPointersVisitor visitor(isolate(), allocated_set); | 528 VerifyPointersVisitor visitor(isolate(), allocated_set); |
494 VisitObjectPointers(&visitor); | 529 VisitObjectPointers(&visitor); |
495 delete allocated_set; | 530 delete allocated_set; |
496 // Only returning a value so that Heap::Validate can be called from an ASSERT. | 531 // Only returning a value so that Heap::Validate can be called from an ASSERT. |
497 return true; | 532 return true; |
498 } | 533 } |
499 | 534 |
500 | 535 |
501 void Heap::PrintSizes() const { | 536 void Heap::PrintSizes() const { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
714 heap->DisableGrowthControl(); | 749 heap->DisableGrowthControl(); |
715 } | 750 } |
716 | 751 |
717 | 752 |
718 NoHeapGrowthControlScope::~NoHeapGrowthControlScope() { | 753 NoHeapGrowthControlScope::~NoHeapGrowthControlScope() { |
719 Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap(); | 754 Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap(); |
720 heap->SetGrowthControlState(current_growth_controller_state_); | 755 heap->SetGrowthControlState(current_growth_controller_state_); |
721 } | 756 } |
722 | 757 |
723 } // namespace dart | 758 } // namespace dart |
OLD | NEW |