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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 ring_buffer_end_(0), | 155 ring_buffer_end_(0), |
156 promotion_queue_(this), | 156 promotion_queue_(this), |
157 configured_(false), | 157 configured_(false), |
158 current_gc_flags_(Heap::kNoGCFlags), | 158 current_gc_flags_(Heap::kNoGCFlags), |
159 current_gc_callback_flags_(GCCallbackFlags::kNoGCCallbackFlags), | 159 current_gc_callback_flags_(GCCallbackFlags::kNoGCCallbackFlags), |
160 external_string_table_(this), | 160 external_string_table_(this), |
161 gc_callbacks_depth_(0), | 161 gc_callbacks_depth_(0), |
162 deserialization_complete_(false), | 162 deserialization_complete_(false), |
163 strong_roots_list_(NULL), | 163 strong_roots_list_(NULL), |
164 heap_iterator_depth_(0), | 164 heap_iterator_depth_(0), |
| 165 embedder_heap_tracer_(nullptr), |
| 166 embedder_reference_reporter_(new TracePossibleWrapperReporter(this)), |
165 force_oom_(false) { | 167 force_oom_(false) { |
166 // Allow build-time customization of the max semispace size. Building | 168 // Allow build-time customization of the max semispace size. Building |
167 // V8 with snapshots and a non-default max semispace size is much | 169 // V8 with snapshots and a non-default max semispace size is much |
168 // easier if you can define it as part of the build environment. | 170 // easier if you can define it as part of the build environment. |
169 #if defined(V8_MAX_SEMISPACE_SIZE) | 171 #if defined(V8_MAX_SEMISPACE_SIZE) |
170 max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; | 172 max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; |
171 #endif | 173 #endif |
172 | 174 |
173 // Ensure old_generation_size_ is a multiple of kPageSize. | 175 // Ensure old_generation_size_ is a multiple of kPageSize. |
174 DCHECK((max_old_generation_size_ & (Page::kPageSize - 1)) == 0); | 176 DCHECK((max_old_generation_size_ & (Page::kPageSize - 1)) == 0); |
(...skipping 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1608 | 1610 |
1609 // Used for updating survived_since_last_expansion_ at function end. | 1611 // Used for updating survived_since_last_expansion_ at function end. |
1610 intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); | 1612 intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); |
1611 | 1613 |
1612 scavenge_collector_->SelectScavengingVisitorsTable(); | 1614 scavenge_collector_->SelectScavengingVisitorsTable(); |
1613 | 1615 |
1614 if (UsingEmbedderHeapTracer()) { | 1616 if (UsingEmbedderHeapTracer()) { |
1615 // Register found wrappers with embedder so it can add them to its marking | 1617 // Register found wrappers with embedder so it can add them to its marking |
1616 // deque and correctly manage the case when v8 scavenger collects the | 1618 // deque and correctly manage the case when v8 scavenger collects the |
1617 // wrappers by either keeping wrappables alive, or cleaning marking deque. | 1619 // wrappers by either keeping wrappables alive, or cleaning marking deque. |
1618 mark_compact_collector()->RegisterWrappersWithEmbedderHeapTracer(); | 1620 RegisterWrappersWithEmbedderHeapTracer(); |
1619 } | 1621 } |
1620 | 1622 |
1621 // Flip the semispaces. After flipping, to space is empty, from space has | 1623 // Flip the semispaces. After flipping, to space is empty, from space has |
1622 // live objects. | 1624 // live objects. |
1623 new_space_->Flip(); | 1625 new_space_->Flip(); |
1624 new_space_->ResetAllocationInfo(); | 1626 new_space_->ResetAllocationInfo(); |
1625 | 1627 |
1626 // We need to sweep newly copied objects which can be either in the | 1628 // We need to sweep newly copied objects which can be either in the |
1627 // to space or promoted to the old generation. For to-space | 1629 // to space or promoted to the old generation. For to-space |
1628 // objects, we treat the bottom of the to space as a queue. Newly | 1630 // objects, we treat the bottom of the to space as a queue. Newly |
(...skipping 2578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4207 ((allocation_throughput != 0) && | 4209 ((allocation_throughput != 0) && |
4208 (allocation_throughput < kLowAllocationThroughput))) { | 4210 (allocation_throughput < kLowAllocationThroughput))) { |
4209 new_space_->Shrink(); | 4211 new_space_->Shrink(); |
4210 UncommitFromSpace(); | 4212 UncommitFromSpace(); |
4211 } | 4213 } |
4212 } | 4214 } |
4213 | 4215 |
4214 bool Heap::MarkingDequesAreEmpty() { | 4216 bool Heap::MarkingDequesAreEmpty() { |
4215 return mark_compact_collector()->marking_deque()->IsEmpty() && | 4217 return mark_compact_collector()->marking_deque()->IsEmpty() && |
4216 (!UsingEmbedderHeapTracer() || | 4218 (!UsingEmbedderHeapTracer() || |
4217 (mark_compact_collector()->wrappers_to_trace() == 0 && | 4219 (wrappers_to_trace() == 0 && |
4218 mark_compact_collector() | 4220 embedder_heap_tracer()->NumberOfWrappersToTrace() == 0)); |
4219 ->embedder_heap_tracer() | |
4220 ->NumberOfWrappersToTrace() == 0)); | |
4221 } | 4221 } |
4222 | 4222 |
4223 void Heap::FinalizeIncrementalMarkingIfComplete( | 4223 void Heap::FinalizeIncrementalMarkingIfComplete( |
4224 GarbageCollectionReason gc_reason) { | 4224 GarbageCollectionReason gc_reason) { |
4225 if (incremental_marking()->IsMarking() && | 4225 if (incremental_marking()->IsMarking() && |
4226 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || | 4226 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || |
4227 (!incremental_marking()->finalize_marking_completed() && | 4227 (!incremental_marking()->finalize_marking_completed() && |
4228 MarkingDequesAreEmpty()))) { | 4228 MarkingDequesAreEmpty()))) { |
4229 FinalizeIncrementalMarking(gc_reason); | 4229 FinalizeIncrementalMarking(gc_reason); |
4230 } else if (incremental_marking()->IsComplete() || | 4230 } else if (incremental_marking()->IsComplete() || |
(...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5554 for (Page* p : *s) { | 5554 for (Page* p : *s) { |
5555 CHECK(p->NeverEvacuate()); | 5555 CHECK(p->NeverEvacuate()); |
5556 } | 5556 } |
5557 #endif // DEBUG | 5557 #endif // DEBUG |
5558 } | 5558 } |
5559 | 5559 |
5560 deserialization_complete_ = true; | 5560 deserialization_complete_ = true; |
5561 } | 5561 } |
5562 | 5562 |
5563 void Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { | 5563 void Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { |
5564 mark_compact_collector()->SetEmbedderHeapTracer(tracer); | 5564 DCHECK_NOT_NULL(tracer); |
| 5565 CHECK_NULL(embedder_heap_tracer_); |
| 5566 embedder_heap_tracer_ = tracer; |
5565 } | 5567 } |
5566 | 5568 |
5567 bool Heap::UsingEmbedderHeapTracer() { | 5569 void Heap::RegisterWrappersWithEmbedderHeapTracer() { |
5568 return mark_compact_collector()->UsingEmbedderHeapTracer(); | 5570 DCHECK(UsingEmbedderHeapTracer()); |
| 5571 if (wrappers_to_trace_.empty()) { |
| 5572 return; |
| 5573 } |
| 5574 embedder_heap_tracer()->RegisterV8References(wrappers_to_trace_); |
| 5575 wrappers_to_trace_.clear(); |
5569 } | 5576 } |
5570 | 5577 |
5571 void Heap::TracePossibleWrapper(JSObject* js_object) { | 5578 void Heap::TracePossibleWrapper(JSObject* js_object) { |
5572 mark_compact_collector()->TracePossibleWrapper(js_object); | 5579 DCHECK(js_object->WasConstructedFromApiFunction()); |
| 5580 if (js_object->GetInternalFieldCount() >= 2 && |
| 5581 js_object->GetInternalField(0) && |
| 5582 js_object->GetInternalField(0) != undefined_value() && |
| 5583 js_object->GetInternalField(1) != undefined_value()) { |
| 5584 DCHECK(reinterpret_cast<intptr_t>(js_object->GetInternalField(0)) % 2 == 0); |
| 5585 wrappers_to_trace_.push_back(std::pair<void*, void*>( |
| 5586 reinterpret_cast<void*>(js_object->GetInternalField(0)), |
| 5587 reinterpret_cast<void*>(js_object->GetInternalField(1)))); |
| 5588 } |
| 5589 } |
| 5590 |
| 5591 bool Heap::RequiresImmediateWrapperProcessing() { |
| 5592 const size_t kTooManyWrappers = 16000; |
| 5593 return wrappers_to_trace_.size() > kTooManyWrappers; |
5573 } | 5594 } |
5574 | 5595 |
5575 void Heap::RegisterExternallyReferencedObject(Object** object) { | 5596 void Heap::RegisterExternallyReferencedObject(Object** object) { |
5576 HeapObject* heap_object = HeapObject::cast(*object); | 5597 HeapObject* heap_object = HeapObject::cast(*object); |
5577 DCHECK(Contains(heap_object)); | 5598 DCHECK(Contains(heap_object)); |
5578 if (FLAG_incremental_marking_wrappers && incremental_marking()->IsMarking()) { | 5599 if (FLAG_incremental_marking_wrappers && incremental_marking()->IsMarking()) { |
5579 IncrementalMarking::MarkGrey(this, heap_object); | 5600 IncrementalMarking::MarkGrey(this, heap_object); |
5580 } else { | 5601 } else { |
5581 DCHECK(mark_compact_collector()->in_use()); | 5602 DCHECK(mark_compact_collector()->in_use()); |
5582 MarkBit mark_bit = ObjectMarking::MarkBitFrom(heap_object); | 5603 MarkBit mark_bit = ObjectMarking::MarkBitFrom(heap_object); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5707 next = list->next; | 5728 next = list->next; |
5708 delete list; | 5729 delete list; |
5709 } | 5730 } |
5710 strong_roots_list_ = NULL; | 5731 strong_roots_list_ = NULL; |
5711 | 5732 |
5712 delete store_buffer_; | 5733 delete store_buffer_; |
5713 store_buffer_ = nullptr; | 5734 store_buffer_ = nullptr; |
5714 | 5735 |
5715 delete memory_allocator_; | 5736 delete memory_allocator_; |
5716 memory_allocator_ = nullptr; | 5737 memory_allocator_ = nullptr; |
| 5738 |
| 5739 delete embedder_reference_reporter_; |
| 5740 embedder_reference_reporter_ = nullptr; |
5717 } | 5741 } |
5718 | 5742 |
5719 | 5743 |
5720 void Heap::AddGCPrologueCallback(v8::Isolate::GCCallback callback, | 5744 void Heap::AddGCPrologueCallback(v8::Isolate::GCCallback callback, |
5721 GCType gc_type, bool pass_isolate) { | 5745 GCType gc_type, bool pass_isolate) { |
5722 DCHECK(callback != NULL); | 5746 DCHECK(callback != NULL); |
5723 GCCallbackPair pair(callback, gc_type, pass_isolate); | 5747 GCCallbackPair pair(callback, gc_type, pass_isolate); |
5724 DCHECK(!gc_prologue_callbacks_.Contains(pair)); | 5748 DCHECK(!gc_prologue_callbacks_.Contains(pair)); |
5725 return gc_prologue_callbacks_.Add(pair); | 5749 return gc_prologue_callbacks_.Add(pair); |
5726 } | 5750 } |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6540 } | 6564 } |
6541 | 6565 |
6542 | 6566 |
6543 // static | 6567 // static |
6544 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6568 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6545 return StaticVisitorBase::GetVisitorId(map); | 6569 return StaticVisitorBase::GetVisitorId(map); |
6546 } | 6570 } |
6547 | 6571 |
6548 } // namespace internal | 6572 } // namespace internal |
6549 } // namespace v8 | 6573 } // namespace v8 |
OLD | NEW |