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 |