| 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/scopeinfo.h" |     9 #include "src/ast/scopeinfo.h" | 
|    10 #include "src/base/bits.h" |    10 #include "src/base/bits.h" | 
| (...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   886   // garbage. |   886   // garbage. | 
|   887   // Note: as weak callbacks can execute arbitrary code, we cannot |   887   // Note: as weak callbacks can execute arbitrary code, we cannot | 
|   888   // hope that eventually there will be no weak callbacks invocations. |   888   // hope that eventually there will be no weak callbacks invocations. | 
|   889   // Therefore stop recollecting after several attempts. |   889   // Therefore stop recollecting after several attempts. | 
|   890   if (isolate()->concurrent_recompilation_enabled()) { |   890   if (isolate()->concurrent_recompilation_enabled()) { | 
|   891     // The optimizing compiler may be unnecessarily holding on to memory. |   891     // The optimizing compiler may be unnecessarily holding on to memory. | 
|   892     DisallowHeapAllocation no_recursive_gc; |   892     DisallowHeapAllocation no_recursive_gc; | 
|   893     isolate()->optimizing_compile_dispatcher()->Flush(); |   893     isolate()->optimizing_compile_dispatcher()->Flush(); | 
|   894   } |   894   } | 
|   895   isolate()->ClearSerializerData(); |   895   isolate()->ClearSerializerData(); | 
|   896   set_current_gc_flags(kMakeHeapIterableMask | kReduceMemoryFootprintMask); |   896   set_current_gc_flags(kAbortIncrementalMarkingMask | | 
 |   897                        kReduceMemoryFootprintMask); | 
|   897   isolate_->compilation_cache()->Clear(); |   898   isolate_->compilation_cache()->Clear(); | 
|   898   const int kMaxNumberOfAttempts = 7; |   899   const int kMaxNumberOfAttempts = 7; | 
|   899   const int kMinNumberOfAttempts = 2; |   900   const int kMinNumberOfAttempts = 2; | 
|   900   for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) { |   901   for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) { | 
|   901     if (!CollectGarbage(MARK_COMPACTOR, gc_reason, NULL, |   902     if (!CollectGarbage(MARK_COMPACTOR, gc_reason, NULL, | 
|   902                         v8::kGCCallbackFlagCollectAllAvailableGarbage) && |   903                         v8::kGCCallbackFlagCollectAllAvailableGarbage) && | 
|   903         attempt + 1 >= kMinNumberOfAttempts) { |   904         attempt + 1 >= kMinNumberOfAttempts) { | 
|   904       break; |   905       break; | 
|   905     } |   906     } | 
|   906   } |   907   } | 
| (...skipping 3131 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4038   Struct* result = nullptr; |  4039   Struct* result = nullptr; | 
|  4039   { |  4040   { | 
|  4040     AllocationResult allocation = Allocate(map, OLD_SPACE); |  4041     AllocationResult allocation = Allocate(map, OLD_SPACE); | 
|  4041     if (!allocation.To(&result)) return allocation; |  4042     if (!allocation.To(&result)) return allocation; | 
|  4042   } |  4043   } | 
|  4043   result->InitializeBody(size); |  4044   result->InitializeBody(size); | 
|  4044   return result; |  4045   return result; | 
|  4045 } |  4046 } | 
|  4046  |  4047  | 
|  4047  |  4048  | 
|  4048 bool Heap::IsHeapIterable() { |  | 
|  4049   // TODO(hpayer): This function is not correct. Allocation folding in old |  | 
|  4050   // space breaks the iterability. |  | 
|  4051   return new_space_top_after_last_gc_ == new_space()->top(); |  | 
|  4052 } |  | 
|  4053  |  | 
|  4054  |  | 
|  4055 void Heap::MakeHeapIterable() { |  4049 void Heap::MakeHeapIterable() { | 
|  4056   DCHECK(AllowHeapAllocation::IsAllowed()); |  | 
|  4057   if (!IsHeapIterable()) { |  | 
|  4058     CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); |  | 
|  4059   } |  | 
|  4060   if (mark_compact_collector()->sweeping_in_progress()) { |  4050   if (mark_compact_collector()->sweeping_in_progress()) { | 
|  4061     mark_compact_collector()->EnsureSweepingCompleted(); |  4051     mark_compact_collector()->EnsureSweepingCompleted(); | 
|  4062   } |  4052   } | 
|  4063   DCHECK(IsHeapIterable()); |  | 
|  4064 } |  4053 } | 
|  4065  |  4054  | 
|  4066  |  4055  | 
|  4067 static double ComputeMutatorUtilization(double mutator_speed, double gc_speed) { |  4056 static double ComputeMutatorUtilization(double mutator_speed, double gc_speed) { | 
|  4068   const double kMinMutatorUtilization = 0.0; |  4057   const double kMinMutatorUtilization = 0.0; | 
|  4069   const double kConservativeGcSpeedInBytesPerMillisecond = 200000; |  4058   const double kConservativeGcSpeedInBytesPerMillisecond = 200000; | 
|  4070   if (mutator_speed == 0) return kMinMutatorUtilization; |  4059   if (mutator_speed == 0) return kMinMutatorUtilization; | 
|  4071   if (gc_speed == 0) gc_speed = kConservativeGcSpeedInBytesPerMillisecond; |  4060   if (gc_speed == 0) gc_speed = kConservativeGcSpeedInBytesPerMillisecond; | 
|  4072   // Derivation: |  4061   // Derivation: | 
|  4073   // mutator_utilization = mutator_time / (mutator_time + gc_time) |  4062   // mutator_utilization = mutator_time / (mutator_time + gc_time) | 
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4598       return false; |  4587       return false; | 
|  4599   } |  4588   } | 
|  4600 } |  4589 } | 
|  4601  |  4590  | 
|  4602  |  4591  | 
|  4603 #ifdef VERIFY_HEAP |  4592 #ifdef VERIFY_HEAP | 
|  4604 void Heap::Verify() { |  4593 void Heap::Verify() { | 
|  4605   CHECK(HasBeenSetUp()); |  4594   CHECK(HasBeenSetUp()); | 
|  4606   HandleScope scope(isolate()); |  4595   HandleScope scope(isolate()); | 
|  4607  |  4596  | 
|  4608   if (mark_compact_collector()->sweeping_in_progress()) { |  4597   MakeHeapIterable(); | 
|  4609     // We have to wait here for the sweeper threads to have an iterable heap. |  | 
|  4610     mark_compact_collector()->EnsureSweepingCompleted(); |  | 
|  4611   } |  | 
|  4612  |  4598  | 
|  4613   VerifyPointersVisitor visitor; |  4599   VerifyPointersVisitor visitor; | 
|  4614   IterateRoots(&visitor, VISIT_ONLY_STRONG); |  4600   IterateRoots(&visitor, VISIT_ONLY_STRONG); | 
|  4615  |  4601  | 
|  4616   VerifySmisVisitor smis_visitor; |  4602   VerifySmisVisitor smis_visitor; | 
|  4617   IterateSmiRoots(&smis_visitor); |  4603   IterateSmiRoots(&smis_visitor); | 
|  4618  |  4604  | 
|  4619   new_space_.Verify(); |  4605   new_space_.Verify(); | 
|  4620  |  4606  | 
|  4621   old_space_->Verify(&visitor); |  4607   old_space_->Verify(&visitor); | 
| (...skipping 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5795     case LO_SPACE: |  5781     case LO_SPACE: | 
|  5796       iterator_ = new LargeObjectIterator(heap_->lo_space()); |  5782       iterator_ = new LargeObjectIterator(heap_->lo_space()); | 
|  5797       break; |  5783       break; | 
|  5798   } |  5784   } | 
|  5799  |  5785  | 
|  5800   // Return the newly allocated iterator; |  5786   // Return the newly allocated iterator; | 
|  5801   DCHECK(iterator_ != NULL); |  5787   DCHECK(iterator_ != NULL); | 
|  5802   return iterator_; |  5788   return iterator_; | 
|  5803 } |  5789 } | 
|  5804  |  5790  | 
|  5805  |  5791 HeapIterator::HeapIterator(Heap* heap, HeapObjectsFiltering filtering) | 
|  5806 class HeapObjectsFilter { |  5792     : heap_(heap), space_iterator_(nullptr), object_iterator_(nullptr) { | 
|  5807  public: |  | 
|  5808   virtual ~HeapObjectsFilter() {} |  | 
|  5809   virtual bool SkipObject(HeapObject* object) = 0; |  | 
|  5810 }; |  | 
|  5811  |  | 
|  5812  |  | 
|  5813 class UnreachableObjectsFilter : public HeapObjectsFilter { |  | 
|  5814  public: |  | 
|  5815   explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) { |  | 
|  5816     MarkReachableObjects(); |  | 
|  5817   } |  | 
|  5818  |  | 
|  5819   ~UnreachableObjectsFilter() { |  | 
|  5820     heap_->mark_compact_collector()->ClearMarkbits(); |  | 
|  5821   } |  | 
|  5822  |  | 
|  5823   bool SkipObject(HeapObject* object) { |  | 
|  5824     if (object->IsFiller()) return true; |  | 
|  5825     MarkBit mark_bit = Marking::MarkBitFrom(object); |  | 
|  5826     return Marking::IsWhite(mark_bit); |  | 
|  5827   } |  | 
|  5828  |  | 
|  5829  private: |  | 
|  5830   class MarkingVisitor : public ObjectVisitor { |  | 
|  5831    public: |  | 
|  5832     MarkingVisitor() : marking_stack_(10) {} |  | 
|  5833  |  | 
|  5834     void VisitPointers(Object** start, Object** end) override { |  | 
|  5835       for (Object** p = start; p < end; p++) { |  | 
|  5836         if (!(*p)->IsHeapObject()) continue; |  | 
|  5837         HeapObject* obj = HeapObject::cast(*p); |  | 
|  5838         MarkBit mark_bit = Marking::MarkBitFrom(obj); |  | 
|  5839         if (Marking::IsWhite(mark_bit)) { |  | 
|  5840           Marking::WhiteToBlack(mark_bit); |  | 
|  5841           marking_stack_.Add(obj); |  | 
|  5842         } |  | 
|  5843       } |  | 
|  5844     } |  | 
|  5845  |  | 
|  5846     void TransitiveClosure() { |  | 
|  5847       while (!marking_stack_.is_empty()) { |  | 
|  5848         HeapObject* obj = marking_stack_.RemoveLast(); |  | 
|  5849         obj->Iterate(this); |  | 
|  5850       } |  | 
|  5851     } |  | 
|  5852  |  | 
|  5853    private: |  | 
|  5854     List<HeapObject*> marking_stack_; |  | 
|  5855   }; |  | 
|  5856  |  | 
|  5857   void MarkReachableObjects() { |  | 
|  5858     MarkingVisitor visitor; |  | 
|  5859     heap_->IterateRoots(&visitor, VISIT_ALL); |  | 
|  5860     visitor.TransitiveClosure(); |  | 
|  5861   } |  | 
|  5862  |  | 
|  5863   Heap* heap_; |  | 
|  5864   DisallowHeapAllocation no_allocation_; |  | 
|  5865 }; |  | 
|  5866  |  | 
|  5867  |  | 
|  5868 HeapIterator::HeapIterator(Heap* heap, |  | 
|  5869                            HeapIterator::HeapObjectsFiltering filtering) |  | 
|  5870     : make_heap_iterable_helper_(heap), |  | 
|  5871       no_heap_allocation_(), |  | 
|  5872       heap_(heap), |  | 
|  5873       filtering_(filtering), |  | 
|  5874       filter_(nullptr), |  | 
|  5875       space_iterator_(nullptr), |  | 
|  5876       object_iterator_(nullptr) { |  | 
|  5877   heap_->heap_iterator_start(); |  5793   heap_->heap_iterator_start(); | 
|  5878   // Start the iteration. |  5794   // Start the iteration. | 
|  5879   space_iterator_ = new SpaceIterator(heap_); |  5795   space_iterator_ = new SpaceIterator(heap_); | 
|  5880   switch (filtering_) { |  5796   switch (filtering) { | 
|  5881     case kFilterUnreachable: |  5797     case HeapObjectsFiltering::kFilterUnreachable: | 
|  5882       filter_ = new UnreachableObjectsFilter(heap_); |  5798       heap_->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask, | 
 |  5799                                "filter unreachable objects"); | 
|  5883       break; |  5800       break; | 
|  5884     default: |  5801     default: | 
|  5885       break; |  5802       break; | 
|  5886   } |  5803   } | 
 |  5804   heap_->MakeHeapIterable(); | 
 |  5805   disallow_heap_allocation_ = new DisallowHeapAllocation(); | 
|  5887   object_iterator_ = space_iterator_->next(); |  5806   object_iterator_ = space_iterator_->next(); | 
|  5888 } |  5807 } | 
|  5889  |  5808  | 
|  5890  |  5809  | 
|  5891 HeapIterator::~HeapIterator() { |  5810 HeapIterator::~HeapIterator() { | 
|  5892   heap_->heap_iterator_end(); |  5811   heap_->heap_iterator_end(); | 
|  5893 #ifdef DEBUG |  | 
|  5894   // Assert that in filtering mode we have iterated through all |  | 
|  5895   // objects. Otherwise, heap will be left in an inconsistent state. |  | 
|  5896   if (filtering_ != kNoFiltering) { |  | 
|  5897     DCHECK(object_iterator_ == nullptr); |  | 
|  5898   } |  | 
|  5899 #endif |  | 
|  5900   // Make sure the last iterator is deallocated. |  5812   // Make sure the last iterator is deallocated. | 
|  5901   delete object_iterator_; |  5813   delete object_iterator_; | 
|  5902   delete space_iterator_; |  5814   delete space_iterator_; | 
|  5903   delete filter_; |  5815   delete disallow_heap_allocation_; | 
|  5904 } |  5816 } | 
|  5905  |  5817  | 
|  5906  |  5818  | 
|  5907 HeapObject* HeapIterator::next() { |  5819 HeapObject* HeapIterator::next() { | 
|  5908   if (filter_ == nullptr) return NextObject(); |  | 
|  5909  |  | 
|  5910   HeapObject* obj = NextObject(); |  | 
|  5911   while ((obj != nullptr) && (filter_->SkipObject(obj))) obj = NextObject(); |  | 
|  5912   return obj; |  | 
|  5913 } |  | 
|  5914  |  | 
|  5915  |  | 
|  5916 HeapObject* HeapIterator::NextObject() { |  | 
|  5917   // No iterator means we are done. |  5820   // No iterator means we are done. | 
|  5918   if (object_iterator_ == nullptr) return nullptr; |  5821   if (object_iterator_ == nullptr) return nullptr; | 
|  5919  |  5822  | 
|  5920   if (HeapObject* obj = object_iterator_->next_object()) { |  5823   if (HeapObject* obj = object_iterator_->next_object()) { | 
|  5921     // If the current iterator has more objects we are fine. |  5824     // If the current iterator has more objects we are fine. | 
|  5922     return obj; |  5825     return obj; | 
|  5923   } else { |  5826   } else { | 
|  5924     // Go though the spaces looking for one that has objects. |  5827     // Go though the spaces looking for one that has objects. | 
|  5925     while (space_iterator_->has_next()) { |  5828     while (space_iterator_->has_next()) { | 
|  5926       object_iterator_ = space_iterator_->next(); |  5829       object_iterator_ = space_iterator_->next(); | 
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6360 } |  6263 } | 
|  6361  |  6264  | 
|  6362  |  6265  | 
|  6363 // static |  6266 // static | 
|  6364 int Heap::GetStaticVisitorIdForMap(Map* map) { |  6267 int Heap::GetStaticVisitorIdForMap(Map* map) { | 
|  6365   return StaticVisitorBase::GetVisitorId(map); |  6268   return StaticVisitorBase::GetVisitorId(map); | 
|  6366 } |  6269 } | 
|  6367  |  6270  | 
|  6368 }  // namespace internal |  6271 }  // namespace internal | 
|  6369 }  // namespace v8 |  6272 }  // namespace v8 | 
| OLD | NEW |