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/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2990 private: | 2990 private: |
2991 static const int kInitialLocalPretenuringFeedbackCapacity = 256; | 2991 static const int kInitialLocalPretenuringFeedbackCapacity = 256; |
2992 | 2992 |
2993 Heap* heap() { return collector_->heap(); } | 2993 Heap* heap() { return collector_->heap(); } |
2994 | 2994 |
2995 void ReportCompactionProgress(double duration, intptr_t bytes_compacted) { | 2995 void ReportCompactionProgress(double duration, intptr_t bytes_compacted) { |
2996 duration_ += duration; | 2996 duration_ += duration; |
2997 bytes_compacted_ += bytes_compacted; | 2997 bytes_compacted_ += bytes_compacted; |
2998 } | 2998 } |
2999 | 2999 |
| 3000 template <IterationMode mode> |
3000 inline bool EvacuateSinglePage(MemoryChunk* p, HeapObjectVisitor* visitor); | 3001 inline bool EvacuateSinglePage(MemoryChunk* p, HeapObjectVisitor* visitor); |
3001 | 3002 |
3002 MarkCompactCollector* collector_; | 3003 MarkCompactCollector* collector_; |
3003 | 3004 |
3004 // Locally cached collector data. | 3005 // Locally cached collector data. |
3005 CompactionSpaceCollection compaction_spaces_; | 3006 CompactionSpaceCollection compaction_spaces_; |
3006 HashMap local_pretenuring_feedback_; | 3007 HashMap local_pretenuring_feedback_; |
3007 | 3008 |
3008 // Visitors for the corresponding spaces. | 3009 // Visitors for the corresponding spaces. |
3009 EvacuateNewSpaceVisitor new_space_visitor_; | 3010 EvacuateNewSpaceVisitor new_space_visitor_; |
3010 EvacuateOldSpaceVisitor old_space_visitor_; | 3011 EvacuateOldSpaceVisitor old_space_visitor_; |
3011 | 3012 |
3012 // Book keeping info. | 3013 // Book keeping info. |
3013 double duration_; | 3014 double duration_; |
3014 intptr_t bytes_compacted_; | 3015 intptr_t bytes_compacted_; |
3015 }; | 3016 }; |
3016 | 3017 |
| 3018 template <MarkCompactCollector::IterationMode mode> |
3017 bool MarkCompactCollector::Evacuator::EvacuateSinglePage( | 3019 bool MarkCompactCollector::Evacuator::EvacuateSinglePage( |
3018 MemoryChunk* p, HeapObjectVisitor* visitor) { | 3020 MemoryChunk* p, HeapObjectVisitor* visitor) { |
3019 bool success = false; | 3021 bool success = false; |
3020 DCHECK(p->IsEvacuationCandidate() || p->InNewSpace()); | 3022 DCHECK(p->IsEvacuationCandidate() || p->InNewSpace()); |
3021 int saved_live_bytes = p->LiveBytes(); | 3023 int saved_live_bytes = p->LiveBytes(); |
3022 double evacuation_time; | 3024 double evacuation_time; |
3023 { | 3025 { |
3024 AlwaysAllocateScope always_allocate(heap()->isolate()); | 3026 AlwaysAllocateScope always_allocate(heap()->isolate()); |
3025 TimedScope timed_scope(&evacuation_time); | 3027 TimedScope timed_scope(&evacuation_time); |
3026 success = collector_->VisitLiveObjects(p, visitor, kClearMarkbits); | 3028 success = collector_->VisitLiveObjects(p, visitor, mode); |
3027 } | 3029 } |
3028 if (FLAG_trace_evacuation) { | 3030 if (FLAG_trace_evacuation) { |
3029 const char age_mark_tag = | 3031 const char age_mark_tag = |
3030 !p->InNewSpace() | 3032 !p->InNewSpace() |
3031 ? 'x' | 3033 ? 'x' |
3032 : !p->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) | 3034 : !p->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) |
3033 ? '>' | 3035 ? '>' |
3034 : !p->ContainsLimit(heap()->new_space()->age_mark()) ? '<' | 3036 : !p->ContainsLimit(heap()->new_space()->age_mark()) ? '<' |
3035 : '#'; | 3037 : '#'; |
3036 PrintIsolate(heap()->isolate(), | 3038 PrintIsolate(heap()->isolate(), |
3037 "evacuation[%p]: page=%p new_space=%d age_mark_tag=%c " | 3039 "evacuation[%p]: page=%p new_space=%d age_mark_tag=%c " |
3038 "executable=%d live_bytes=%d time=%f\n", | 3040 "executable=%d live_bytes=%d time=%f\n", |
3039 this, p, p->InNewSpace(), age_mark_tag, | 3041 this, p, p->InNewSpace(), age_mark_tag, |
3040 p->IsFlagSet(MemoryChunk::IS_EXECUTABLE), saved_live_bytes, | 3042 p->IsFlagSet(MemoryChunk::IS_EXECUTABLE), saved_live_bytes, |
3041 evacuation_time); | 3043 evacuation_time); |
3042 } | 3044 } |
3043 if (success) { | 3045 if (success) { |
3044 ReportCompactionProgress(evacuation_time, saved_live_bytes); | 3046 ReportCompactionProgress(evacuation_time, saved_live_bytes); |
3045 } | 3047 } |
3046 return success; | 3048 return success; |
3047 } | 3049 } |
3048 | 3050 |
3049 bool MarkCompactCollector::Evacuator::EvacuatePage(MemoryChunk* chunk) { | 3051 bool MarkCompactCollector::Evacuator::EvacuatePage(MemoryChunk* chunk) { |
3050 bool success = false; | 3052 bool success = false; |
3051 if (chunk->InNewSpace()) { | 3053 if (chunk->InNewSpace()) { |
3052 DCHECK_EQ(chunk->concurrent_sweeping_state().Value(), | 3054 DCHECK_EQ(chunk->concurrent_sweeping_state().Value(), |
3053 NewSpacePage::kSweepingDone); | 3055 NewSpacePage::kSweepingDone); |
3054 success = EvacuateSinglePage(chunk, &new_space_visitor_); | 3056 success = EvacuateSinglePage<kClearMarkbits>(chunk, &new_space_visitor_); |
3055 DCHECK(success); | 3057 DCHECK(success); |
3056 USE(success); | 3058 USE(success); |
3057 } else { | 3059 } else { |
3058 DCHECK(chunk->IsEvacuationCandidate()); | 3060 DCHECK(chunk->IsEvacuationCandidate()); |
3059 DCHECK_EQ(chunk->concurrent_sweeping_state().Value(), Page::kSweepingDone); | 3061 DCHECK_EQ(chunk->concurrent_sweeping_state().Value(), Page::kSweepingDone); |
3060 success = EvacuateSinglePage(chunk, &old_space_visitor_); | 3062 success = EvacuateSinglePage<kClearMarkbits>(chunk, &old_space_visitor_); |
3061 } | 3063 } |
3062 return success; | 3064 return success; |
3063 } | 3065 } |
3064 | 3066 |
3065 void MarkCompactCollector::Evacuator::Finalize() { | 3067 void MarkCompactCollector::Evacuator::Finalize() { |
3066 heap()->old_space()->MergeCompactionSpace(compaction_spaces_.Get(OLD_SPACE)); | 3068 heap()->old_space()->MergeCompactionSpace(compaction_spaces_.Get(OLD_SPACE)); |
3067 heap()->code_space()->MergeCompactionSpace( | 3069 heap()->code_space()->MergeCompactionSpace( |
3068 compaction_spaces_.Get(CODE_SPACE)); | 3070 compaction_spaces_.Get(CODE_SPACE)); |
3069 heap()->tracer()->AddCompactionEvent(duration_, bytes_compacted_); | 3071 heap()->tracer()->AddCompactionEvent(duration_, bytes_compacted_); |
3070 heap()->IncrementPromotedObjectsSize(new_space_visitor_.promoted_size()); | 3072 heap()->IncrementPromotedObjectsSize(new_space_visitor_.promoted_size()); |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3847 MarkBit mark_bit = Marking::MarkBitFrom(host); | 3849 MarkBit mark_bit = Marking::MarkBitFrom(host); |
3848 if (Marking::IsBlack(mark_bit)) { | 3850 if (Marking::IsBlack(mark_bit)) { |
3849 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 3851 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
3850 RecordRelocSlot(host, &rinfo, target); | 3852 RecordRelocSlot(host, &rinfo, target); |
3851 } | 3853 } |
3852 } | 3854 } |
3853 } | 3855 } |
3854 | 3856 |
3855 } // namespace internal | 3857 } // namespace internal |
3856 } // namespace v8 | 3858 } // namespace v8 |
OLD | NEW |