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