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