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