OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/heap.h" | 5 #include "src/heap/heap.h" |
6 | 6 |
| 7 #include <unordered_map> |
| 8 #include <unordered_set> |
| 9 |
7 #include "src/accessors.h" | 10 #include "src/accessors.h" |
8 #include "src/api.h" | 11 #include "src/api.h" |
9 #include "src/assembler-inl.h" | 12 #include "src/assembler-inl.h" |
10 #include "src/ast/context-slot-cache.h" | 13 #include "src/ast/context-slot-cache.h" |
11 #include "src/base/bits.h" | 14 #include "src/base/bits.h" |
12 #include "src/base/once.h" | 15 #include "src/base/once.h" |
13 #include "src/base/utils/random-number-generator.h" | 16 #include "src/base/utils/random-number-generator.h" |
14 #include "src/bootstrapper.h" | 17 #include "src/bootstrapper.h" |
15 #include "src/codegen.h" | 18 #include "src/codegen.h" |
16 #include "src/compilation-cache.h" | 19 #include "src/compilation-cache.h" |
(...skipping 6217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6234 }; | 6237 }; |
6235 | 6238 |
6236 | 6239 |
6237 class UnreachableObjectsFilter : public HeapObjectsFilter { | 6240 class UnreachableObjectsFilter : public HeapObjectsFilter { |
6238 public: | 6241 public: |
6239 explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) { | 6242 explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) { |
6240 MarkReachableObjects(); | 6243 MarkReachableObjects(); |
6241 } | 6244 } |
6242 | 6245 |
6243 ~UnreachableObjectsFilter() { | 6246 ~UnreachableObjectsFilter() { |
6244 heap_->mark_compact_collector()->ClearMarkbits(); | 6247 for (auto it : reachable_) { |
| 6248 delete it.second; |
| 6249 it.second = nullptr; |
| 6250 } |
6245 } | 6251 } |
6246 | 6252 |
6247 bool SkipObject(HeapObject* object) { | 6253 bool SkipObject(HeapObject* object) { |
6248 if (object->IsFiller()) return true; | 6254 if (object->IsFiller()) return true; |
6249 return ObjectMarking::IsWhite(object, MarkingState::Internal(object)); | 6255 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); |
| 6256 if (reachable_.count(chunk) == 0) return true; |
| 6257 return reachable_[chunk]->count(object) == 0; |
6250 } | 6258 } |
6251 | 6259 |
6252 private: | 6260 private: |
| 6261 bool MarkAsReachable(HeapObject* object) { |
| 6262 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); |
| 6263 if (reachable_.count(chunk) == 0) { |
| 6264 reachable_[chunk] = new std::unordered_set<HeapObject*>(); |
| 6265 } |
| 6266 if (reachable_[chunk]->count(object)) return false; |
| 6267 reachable_[chunk]->insert(object); |
| 6268 return true; |
| 6269 } |
| 6270 |
6253 class MarkingVisitor : public ObjectVisitor, public RootVisitor { | 6271 class MarkingVisitor : public ObjectVisitor, public RootVisitor { |
6254 public: | 6272 public: |
6255 MarkingVisitor() : marking_stack_(10) {} | 6273 explicit MarkingVisitor(UnreachableObjectsFilter* filter) |
| 6274 : filter_(filter), marking_stack_(10) {} |
6256 | 6275 |
6257 void VisitPointers(HeapObject* host, Object** start, | 6276 void VisitPointers(HeapObject* host, Object** start, |
6258 Object** end) override { | 6277 Object** end) override { |
6259 MarkPointers(start, end); | 6278 MarkPointers(start, end); |
6260 } | 6279 } |
6261 | 6280 |
6262 void VisitRootPointers(Root root, Object** start, Object** end) override { | 6281 void VisitRootPointers(Root root, Object** start, Object** end) override { |
6263 MarkPointers(start, end); | 6282 MarkPointers(start, end); |
6264 } | 6283 } |
6265 | 6284 |
6266 void TransitiveClosure() { | 6285 void TransitiveClosure() { |
6267 while (!marking_stack_.is_empty()) { | 6286 while (!marking_stack_.is_empty()) { |
6268 HeapObject* obj = marking_stack_.RemoveLast(); | 6287 HeapObject* obj = marking_stack_.RemoveLast(); |
6269 obj->Iterate(this); | 6288 obj->Iterate(this); |
6270 } | 6289 } |
6271 } | 6290 } |
6272 | 6291 |
6273 private: | 6292 private: |
6274 void MarkPointers(Object** start, Object** end) { | 6293 void MarkPointers(Object** start, Object** end) { |
6275 for (Object** p = start; p < end; p++) { | 6294 for (Object** p = start; p < end; p++) { |
6276 if (!(*p)->IsHeapObject()) continue; | 6295 if (!(*p)->IsHeapObject()) continue; |
6277 HeapObject* obj = HeapObject::cast(*p); | 6296 HeapObject* obj = HeapObject::cast(*p); |
6278 // Use Marking instead of ObjectMarking to avoid adjusting live bytes | 6297 if (filter_->MarkAsReachable(obj)) { |
6279 // counter. | |
6280 MarkBit mark_bit = | |
6281 ObjectMarking::MarkBitFrom(obj, MarkingState::Internal(obj)); | |
6282 if (Marking::IsWhite(mark_bit)) { | |
6283 Marking::WhiteToBlack(mark_bit); | |
6284 marking_stack_.Add(obj); | 6298 marking_stack_.Add(obj); |
6285 } | 6299 } |
6286 } | 6300 } |
6287 } | 6301 } |
| 6302 UnreachableObjectsFilter* filter_; |
6288 List<HeapObject*> marking_stack_; | 6303 List<HeapObject*> marking_stack_; |
6289 }; | 6304 }; |
6290 | 6305 |
| 6306 friend class MarkingVisitor; |
| 6307 |
6291 void MarkReachableObjects() { | 6308 void MarkReachableObjects() { |
6292 MarkingVisitor visitor; | 6309 MarkingVisitor visitor(this); |
6293 heap_->IterateRoots(&visitor, VISIT_ALL); | 6310 heap_->IterateRoots(&visitor, VISIT_ALL); |
6294 visitor.TransitiveClosure(); | 6311 visitor.TransitiveClosure(); |
6295 } | 6312 } |
6296 | 6313 |
6297 Heap* heap_; | 6314 Heap* heap_; |
6298 DisallowHeapAllocation no_allocation_; | 6315 DisallowHeapAllocation no_allocation_; |
| 6316 std::unordered_map<MemoryChunk*, std::unordered_set<HeapObject*>*> reachable_; |
6299 }; | 6317 }; |
6300 | 6318 |
6301 HeapIterator::HeapIterator(Heap* heap, | 6319 HeapIterator::HeapIterator(Heap* heap, |
6302 HeapIterator::HeapObjectsFiltering filtering) | 6320 HeapIterator::HeapObjectsFiltering filtering) |
6303 : no_heap_allocation_(), | 6321 : no_heap_allocation_(), |
6304 heap_(heap), | 6322 heap_(heap), |
6305 filtering_(filtering), | 6323 filtering_(filtering), |
6306 filter_(nullptr), | 6324 filter_(nullptr), |
6307 space_iterator_(nullptr), | 6325 space_iterator_(nullptr), |
6308 object_iterator_(nullptr) { | 6326 object_iterator_(nullptr) { |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6563 case LO_SPACE: | 6581 case LO_SPACE: |
6564 return "LO_SPACE"; | 6582 return "LO_SPACE"; |
6565 default: | 6583 default: |
6566 UNREACHABLE(); | 6584 UNREACHABLE(); |
6567 } | 6585 } |
6568 return NULL; | 6586 return NULL; |
6569 } | 6587 } |
6570 | 6588 |
6571 } // namespace internal | 6589 } // namespace internal |
6572 } // namespace v8 | 6590 } // namespace v8 |
OLD | NEW |