| 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 "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/ast/context-slot-cache.h" | 9 #include "src/ast/context-slot-cache.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 5405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5416 if (!memory_allocator_->SetUp(MaxReserved(), MaxExecutableSize(), | 5416 if (!memory_allocator_->SetUp(MaxReserved(), MaxExecutableSize(), |
| 5417 code_range_size_)) | 5417 code_range_size_)) |
| 5418 return false; | 5418 return false; |
| 5419 | 5419 |
| 5420 // Initialize store buffer. | 5420 // Initialize store buffer. |
| 5421 store_buffer_ = new StoreBuffer(this); | 5421 store_buffer_ = new StoreBuffer(this); |
| 5422 | 5422 |
| 5423 // Initialize incremental marking. | 5423 // Initialize incremental marking. |
| 5424 incremental_marking_ = new IncrementalMarking(this); | 5424 incremental_marking_ = new IncrementalMarking(this); |
| 5425 | 5425 |
| 5426 new_space_ = new NewSpace(this); | 5426 for (int i = 0; i <= LAST_SPACE; i++) { |
| 5427 space_[i] = nullptr; |
| 5428 } |
| 5429 |
| 5430 space_[NEW_SPACE] = new_space_ = new NewSpace(this); |
| 5427 if (new_space_ == nullptr) return false; | 5431 if (new_space_ == nullptr) return false; |
| 5428 | 5432 |
| 5429 // Set up new space. | 5433 // Set up new space. |
| 5430 if (!new_space_->SetUp(initial_semispace_size_, max_semi_space_size_)) { | 5434 if (!new_space_->SetUp(initial_semispace_size_, max_semi_space_size_)) { |
| 5431 return false; | 5435 return false; |
| 5432 } | 5436 } |
| 5433 new_space_top_after_last_gc_ = new_space()->top(); | 5437 new_space_top_after_last_gc_ = new_space()->top(); |
| 5434 | 5438 |
| 5435 // Initialize old space. | 5439 // Initialize old space. |
| 5436 old_space_ = new OldSpace(this, OLD_SPACE, NOT_EXECUTABLE); | 5440 space_[OLD_SPACE] = old_space_ = |
| 5441 new OldSpace(this, OLD_SPACE, NOT_EXECUTABLE); |
| 5437 if (old_space_ == NULL) return false; | 5442 if (old_space_ == NULL) return false; |
| 5438 if (!old_space_->SetUp()) return false; | 5443 if (!old_space_->SetUp()) return false; |
| 5439 | 5444 |
| 5440 // Initialize the code space, set its maximum capacity to the old | 5445 // Initialize the code space, set its maximum capacity to the old |
| 5441 // generation size. It needs executable memory. | 5446 // generation size. It needs executable memory. |
| 5442 code_space_ = new OldSpace(this, CODE_SPACE, EXECUTABLE); | 5447 space_[CODE_SPACE] = code_space_ = new OldSpace(this, CODE_SPACE, EXECUTABLE); |
| 5443 if (code_space_ == NULL) return false; | 5448 if (code_space_ == NULL) return false; |
| 5444 if (!code_space_->SetUp()) return false; | 5449 if (!code_space_->SetUp()) return false; |
| 5445 | 5450 |
| 5446 // Initialize map space. | 5451 // Initialize map space. |
| 5447 map_space_ = new MapSpace(this, MAP_SPACE); | 5452 space_[MAP_SPACE] = map_space_ = new MapSpace(this, MAP_SPACE); |
| 5448 if (map_space_ == NULL) return false; | 5453 if (map_space_ == NULL) return false; |
| 5449 if (!map_space_->SetUp()) return false; | 5454 if (!map_space_->SetUp()) return false; |
| 5450 | 5455 |
| 5451 // The large object code space may contain code or data. We set the memory | 5456 // The large object code space may contain code or data. We set the memory |
| 5452 // to be non-executable here for safety, but this means we need to enable it | 5457 // to be non-executable here for safety, but this means we need to enable it |
| 5453 // explicitly when allocating large code objects. | 5458 // explicitly when allocating large code objects. |
| 5454 lo_space_ = new LargeObjectSpace(this, LO_SPACE); | 5459 space_[LO_SPACE] = lo_space_ = new LargeObjectSpace(this, LO_SPACE); |
| 5455 if (lo_space_ == NULL) return false; | 5460 if (lo_space_ == NULL) return false; |
| 5456 if (!lo_space_->SetUp()) return false; | 5461 if (!lo_space_->SetUp()) return false; |
| 5457 | 5462 |
| 5458 // Set up the seed that is used to randomize the string hash function. | 5463 // Set up the seed that is used to randomize the string hash function. |
| 5459 DCHECK(hash_seed() == 0); | 5464 DCHECK(hash_seed() == 0); |
| 5460 if (FLAG_randomize_hashes) { | 5465 if (FLAG_randomize_hashes) { |
| 5461 if (FLAG_hash_seed == 0) { | 5466 if (FLAG_hash_seed == 0) { |
| 5462 int rnd = isolate()->random_number_generator()->NextInt(); | 5467 int rnd = isolate()->random_number_generator()->NextInt(); |
| 5463 set_hash_seed(Smi::FromInt(rnd & Name::kHashBitMask)); | 5468 set_hash_seed(Smi::FromInt(rnd & Name::kHashBitMask)); |
| 5464 } else { | 5469 } else { |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5987 switch (counter_++) { | 5992 switch (counter_++) { |
| 5988 case OLD_SPACE: | 5993 case OLD_SPACE: |
| 5989 return heap_->old_space(); | 5994 return heap_->old_space(); |
| 5990 case CODE_SPACE: | 5995 case CODE_SPACE: |
| 5991 return heap_->code_space(); | 5996 return heap_->code_space(); |
| 5992 default: | 5997 default: |
| 5993 return NULL; | 5998 return NULL; |
| 5994 } | 5999 } |
| 5995 } | 6000 } |
| 5996 | 6001 |
| 5997 | |
| 5998 SpaceIterator::SpaceIterator(Heap* heap) | 6002 SpaceIterator::SpaceIterator(Heap* heap) |
| 5999 : heap_(heap), current_space_(FIRST_SPACE), iterator_(NULL) {} | 6003 : heap_(heap), current_space_(FIRST_SPACE - 1) {} |
| 6000 | |
| 6001 | 6004 |
| 6002 SpaceIterator::~SpaceIterator() { | 6005 SpaceIterator::~SpaceIterator() { |
| 6003 // Delete active iterator if any. | |
| 6004 delete iterator_; | |
| 6005 } | 6006 } |
| 6006 | 6007 |
| 6007 | 6008 |
| 6008 bool SpaceIterator::has_next() { | 6009 bool SpaceIterator::has_next() { |
| 6009 // Iterate until no more spaces. | 6010 // Iterate until no more spaces. |
| 6010 return current_space_ != LAST_SPACE; | 6011 return current_space_ != LAST_SPACE; |
| 6011 } | 6012 } |
| 6012 | 6013 |
| 6013 | 6014 Space* SpaceIterator::next() { |
| 6014 ObjectIterator* SpaceIterator::next() { | 6015 DCHECK(has_next()); |
| 6015 if (iterator_ != NULL) { | 6016 return heap_->space(++current_space_); |
| 6016 delete iterator_; | |
| 6017 iterator_ = NULL; | |
| 6018 // Move to the next space | |
| 6019 current_space_++; | |
| 6020 if (current_space_ > LAST_SPACE) { | |
| 6021 return NULL; | |
| 6022 } | |
| 6023 } | |
| 6024 | |
| 6025 // Return iterator for the new current space. | |
| 6026 return CreateIterator(); | |
| 6027 } | 6017 } |
| 6028 | 6018 |
| 6029 | 6019 |
| 6030 // Create an iterator for the space to iterate. | |
| 6031 ObjectIterator* SpaceIterator::CreateIterator() { | |
| 6032 DCHECK(iterator_ == NULL); | |
| 6033 | |
| 6034 switch (current_space_) { | |
| 6035 case NEW_SPACE: | |
| 6036 iterator_ = new SemiSpaceIterator(heap_->new_space()); | |
| 6037 break; | |
| 6038 case OLD_SPACE: | |
| 6039 iterator_ = new HeapObjectIterator(heap_->old_space()); | |
| 6040 break; | |
| 6041 case CODE_SPACE: | |
| 6042 iterator_ = new HeapObjectIterator(heap_->code_space()); | |
| 6043 break; | |
| 6044 case MAP_SPACE: | |
| 6045 iterator_ = new HeapObjectIterator(heap_->map_space()); | |
| 6046 break; | |
| 6047 case LO_SPACE: | |
| 6048 iterator_ = new LargeObjectIterator(heap_->lo_space()); | |
| 6049 break; | |
| 6050 } | |
| 6051 | |
| 6052 // Return the newly allocated iterator; | |
| 6053 DCHECK(iterator_ != NULL); | |
| 6054 return iterator_; | |
| 6055 } | |
| 6056 | |
| 6057 | |
| 6058 class HeapObjectsFilter { | 6020 class HeapObjectsFilter { |
| 6059 public: | 6021 public: |
| 6060 virtual ~HeapObjectsFilter() {} | 6022 virtual ~HeapObjectsFilter() {} |
| 6061 virtual bool SkipObject(HeapObject* object) = 0; | 6023 virtual bool SkipObject(HeapObject* object) = 0; |
| 6062 }; | 6024 }; |
| 6063 | 6025 |
| 6064 | 6026 |
| 6065 class UnreachableObjectsFilter : public HeapObjectsFilter { | 6027 class UnreachableObjectsFilter : public HeapObjectsFilter { |
| 6066 public: | 6028 public: |
| 6067 explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) { | 6029 explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6129 heap_->heap_iterator_start(); | 6091 heap_->heap_iterator_start(); |
| 6130 // Start the iteration. | 6092 // Start the iteration. |
| 6131 space_iterator_ = new SpaceIterator(heap_); | 6093 space_iterator_ = new SpaceIterator(heap_); |
| 6132 switch (filtering_) { | 6094 switch (filtering_) { |
| 6133 case kFilterUnreachable: | 6095 case kFilterUnreachable: |
| 6134 filter_ = new UnreachableObjectsFilter(heap_); | 6096 filter_ = new UnreachableObjectsFilter(heap_); |
| 6135 break; | 6097 break; |
| 6136 default: | 6098 default: |
| 6137 break; | 6099 break; |
| 6138 } | 6100 } |
| 6139 object_iterator_ = space_iterator_->next(); | 6101 object_iterator_ = space_iterator_->next()->GetObjectIterator(); |
| 6140 } | 6102 } |
| 6141 | 6103 |
| 6142 | 6104 |
| 6143 HeapIterator::~HeapIterator() { | 6105 HeapIterator::~HeapIterator() { |
| 6144 heap_->heap_iterator_end(); | 6106 heap_->heap_iterator_end(); |
| 6145 #ifdef DEBUG | 6107 #ifdef DEBUG |
| 6146 // Assert that in filtering mode we have iterated through all | 6108 // Assert that in filtering mode we have iterated through all |
| 6147 // objects. Otherwise, heap will be left in an inconsistent state. | 6109 // objects. Otherwise, heap will be left in an inconsistent state. |
| 6148 if (filtering_ != kNoFiltering) { | 6110 if (filtering_ != kNoFiltering) { |
| 6149 DCHECK(object_iterator_ == nullptr); | 6111 DCHECK(object_iterator_ == nullptr); |
| 6150 } | 6112 } |
| 6151 #endif | 6113 #endif |
| 6152 // Make sure the last iterator is deallocated. | |
| 6153 delete object_iterator_; | |
| 6154 delete space_iterator_; | 6114 delete space_iterator_; |
| 6155 delete filter_; | 6115 delete filter_; |
| 6156 } | 6116 } |
| 6157 | 6117 |
| 6158 | 6118 |
| 6159 HeapObject* HeapIterator::next() { | 6119 HeapObject* HeapIterator::next() { |
| 6160 if (filter_ == nullptr) return NextObject(); | 6120 if (filter_ == nullptr) return NextObject(); |
| 6161 | 6121 |
| 6162 HeapObject* obj = NextObject(); | 6122 HeapObject* obj = NextObject(); |
| 6163 while ((obj != nullptr) && (filter_->SkipObject(obj))) obj = NextObject(); | 6123 while ((obj != nullptr) && (filter_->SkipObject(obj))) obj = NextObject(); |
| 6164 return obj; | 6124 return obj; |
| 6165 } | 6125 } |
| 6166 | 6126 |
| 6167 | 6127 |
| 6168 HeapObject* HeapIterator::NextObject() { | 6128 HeapObject* HeapIterator::NextObject() { |
| 6169 // No iterator means we are done. | 6129 // No iterator means we are done. |
| 6170 if (object_iterator_ == nullptr) return nullptr; | 6130 if (object_iterator_.get() == nullptr) return nullptr; |
| 6171 | 6131 |
| 6172 if (HeapObject* obj = object_iterator_->Next()) { | 6132 if (HeapObject* obj = object_iterator_.get()->Next()) { |
| 6173 // If the current iterator has more objects we are fine. | 6133 // If the current iterator has more objects we are fine. |
| 6174 return obj; | 6134 return obj; |
| 6175 } else { | 6135 } else { |
| 6176 // Go though the spaces looking for one that has objects. | 6136 // Go though the spaces looking for one that has objects. |
| 6177 while (space_iterator_->has_next()) { | 6137 while (space_iterator_->has_next()) { |
| 6178 object_iterator_ = space_iterator_->next(); | 6138 object_iterator_ = space_iterator_->next()->GetObjectIterator(); |
| 6179 if (HeapObject* obj = object_iterator_->Next()) { | 6139 if (HeapObject* obj = object_iterator_.get()->Next()) { |
| 6180 return obj; | 6140 return obj; |
| 6181 } | 6141 } |
| 6182 } | 6142 } |
| 6183 } | 6143 } |
| 6184 // Done with the last space. | 6144 // Done with the last space. |
| 6185 object_iterator_ = nullptr; | 6145 object_iterator_.reset(nullptr); |
| 6186 return nullptr; | 6146 return nullptr; |
| 6187 } | 6147 } |
| 6188 | 6148 |
| 6189 | 6149 |
| 6190 #ifdef DEBUG | 6150 #ifdef DEBUG |
| 6191 | 6151 |
| 6192 Object* const PathTracer::kAnyGlobalObject = NULL; | 6152 Object* const PathTracer::kAnyGlobalObject = NULL; |
| 6193 | 6153 |
| 6194 class PathTracer::MarkVisitor : public ObjectVisitor { | 6154 class PathTracer::MarkVisitor : public ObjectVisitor { |
| 6195 public: | 6155 public: |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6540 } | 6500 } |
| 6541 | 6501 |
| 6542 | 6502 |
| 6543 // static | 6503 // static |
| 6544 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6504 int Heap::GetStaticVisitorIdForMap(Map* map) { |
| 6545 return StaticVisitorBase::GetVisitorId(map); | 6505 return StaticVisitorBase::GetVisitorId(map); |
| 6546 } | 6506 } |
| 6547 | 6507 |
| 6548 } // namespace internal | 6508 } // namespace internal |
| 6549 } // namespace v8 | 6509 } // namespace v8 |
| OLD | NEW |