| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 state_(IDLE), | 52 state_(IDLE), |
| 53 #endif | 53 #endif |
| 54 marking_parity_(ODD_MARKING_PARITY), | 54 marking_parity_(ODD_MARKING_PARITY), |
| 55 was_marked_incrementally_(false), | 55 was_marked_incrementally_(false), |
| 56 evacuation_(false), | 56 evacuation_(false), |
| 57 slots_buffer_allocator_(nullptr), | 57 slots_buffer_allocator_(nullptr), |
| 58 migration_slots_buffer_(nullptr), | 58 migration_slots_buffer_(nullptr), |
| 59 heap_(heap), | 59 heap_(heap), |
| 60 marking_deque_memory_(NULL), | 60 marking_deque_memory_(NULL), |
| 61 marking_deque_memory_committed_(0), | 61 marking_deque_memory_committed_(0), |
| 62 code_flusher_(NULL), | 62 code_flusher_(nullptr), |
| 63 have_code_to_deoptimize_(false), | 63 have_code_to_deoptimize_(false), |
| 64 compacting_(false), | 64 compacting_(false), |
| 65 sweeping_in_progress_(false), | 65 sweeping_in_progress_(false), |
| 66 compaction_in_progress_(false), | 66 compaction_in_progress_(false), |
| 67 pending_sweeper_tasks_semaphore_(0), | 67 pending_sweeper_tasks_semaphore_(0), |
| 68 pending_compaction_tasks_semaphore_(0) { | 68 pending_compaction_tasks_semaphore_(0) { |
| 69 } | 69 } |
| 70 | 70 |
| 71 #ifdef VERIFY_HEAP | 71 #ifdef VERIFY_HEAP |
| 72 class VerifyMarkingVisitor : public ObjectVisitor { | 72 class VerifyMarkingVisitor : public ObjectVisitor { |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); | 240 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); |
| 241 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); | 241 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); |
| 242 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); | 242 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); |
| 243 | 243 |
| 244 free_list_old_space_.Reset(new FreeList(heap_->old_space())); | 244 free_list_old_space_.Reset(new FreeList(heap_->old_space())); |
| 245 free_list_code_space_.Reset(new FreeList(heap_->code_space())); | 245 free_list_code_space_.Reset(new FreeList(heap_->code_space())); |
| 246 free_list_map_space_.Reset(new FreeList(heap_->map_space())); | 246 free_list_map_space_.Reset(new FreeList(heap_->map_space())); |
| 247 EnsureMarkingDequeIsReserved(); | 247 EnsureMarkingDequeIsReserved(); |
| 248 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); | 248 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); |
| 249 slots_buffer_allocator_ = new SlotsBufferAllocator(); | 249 slots_buffer_allocator_ = new SlotsBufferAllocator(); |
| 250 |
| 251 if (FLAG_flush_code) { |
| 252 code_flusher_ = new CodeFlusher(isolate()); |
| 253 if (FLAG_trace_code_flushing) { |
| 254 PrintF("[code-flushing is now on]\n"); |
| 255 } |
| 256 } |
| 250 } | 257 } |
| 251 | 258 |
| 252 | 259 |
| 253 void MarkCompactCollector::TearDown() { | 260 void MarkCompactCollector::TearDown() { |
| 254 AbortCompaction(); | 261 AbortCompaction(); |
| 255 delete marking_deque_memory_; | 262 delete marking_deque_memory_; |
| 256 delete slots_buffer_allocator_; | 263 delete slots_buffer_allocator_; |
| 264 delete code_flusher_; |
| 257 } | 265 } |
| 258 | 266 |
| 259 | 267 |
| 260 void MarkCompactCollector::AddEvacuationCandidate(Page* p) { | 268 void MarkCompactCollector::AddEvacuationCandidate(Page* p) { |
| 261 DCHECK(!p->NeverEvacuate()); | 269 DCHECK(!p->NeverEvacuate()); |
| 262 p->MarkEvacuationCandidate(); | 270 p->MarkEvacuationCandidate(); |
| 263 evacuation_candidates_.Add(p); | 271 evacuation_candidates_.Add(p); |
| 264 } | 272 } |
| 265 | 273 |
| 266 | 274 |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 ClearNextCandidate(function, undefined); | 1061 ClearNextCandidate(function, undefined); |
| 1054 break; | 1062 break; |
| 1055 } | 1063 } |
| 1056 | 1064 |
| 1057 candidate = next_candidate; | 1065 candidate = next_candidate; |
| 1058 } | 1066 } |
| 1059 } | 1067 } |
| 1060 } | 1068 } |
| 1061 | 1069 |
| 1062 | 1070 |
| 1063 void CodeFlusher::EvictJSFunctionCandidates() { | |
| 1064 JSFunction* candidate = jsfunction_candidates_head_; | |
| 1065 JSFunction* next_candidate; | |
| 1066 while (candidate != NULL) { | |
| 1067 next_candidate = GetNextCandidate(candidate); | |
| 1068 EvictCandidate(candidate); | |
| 1069 candidate = next_candidate; | |
| 1070 } | |
| 1071 DCHECK(jsfunction_candidates_head_ == NULL); | |
| 1072 } | |
| 1073 | |
| 1074 | |
| 1075 void CodeFlusher::EvictSharedFunctionInfoCandidates() { | |
| 1076 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; | |
| 1077 SharedFunctionInfo* next_candidate; | |
| 1078 while (candidate != NULL) { | |
| 1079 next_candidate = GetNextCandidate(candidate); | |
| 1080 EvictCandidate(candidate); | |
| 1081 candidate = next_candidate; | |
| 1082 } | |
| 1083 DCHECK(shared_function_info_candidates_head_ == NULL); | |
| 1084 } | |
| 1085 | |
| 1086 | |
| 1087 void CodeFlusher::IteratePointersToFromSpace(ObjectVisitor* v) { | 1071 void CodeFlusher::IteratePointersToFromSpace(ObjectVisitor* v) { |
| 1088 Heap* heap = isolate_->heap(); | 1072 Heap* heap = isolate_->heap(); |
| 1089 | 1073 |
| 1090 JSFunction** slot = &jsfunction_candidates_head_; | 1074 JSFunction** slot = &jsfunction_candidates_head_; |
| 1091 JSFunction* candidate = jsfunction_candidates_head_; | 1075 JSFunction* candidate = jsfunction_candidates_head_; |
| 1092 while (candidate != NULL) { | 1076 while (candidate != NULL) { |
| 1093 if (heap->InFromSpace(candidate)) { | 1077 if (heap->InFromSpace(candidate)) { |
| 1094 v->VisitPointer(reinterpret_cast<Object**>(slot)); | 1078 v->VisitPointer(reinterpret_cast<Object**>(slot)); |
| 1095 } | 1079 } |
| 1096 candidate = GetNextCandidate(*slot); | 1080 candidate = GetNextCandidate(*slot); |
| 1097 slot = GetNextCandidateSlot(*slot); | 1081 slot = GetNextCandidateSlot(*slot); |
| 1098 } | 1082 } |
| 1099 } | 1083 } |
| 1100 | 1084 |
| 1101 | 1085 |
| 1102 MarkCompactCollector::~MarkCompactCollector() { | |
| 1103 if (code_flusher_ != NULL) { | |
| 1104 delete code_flusher_; | |
| 1105 code_flusher_ = NULL; | |
| 1106 } | |
| 1107 } | |
| 1108 | |
| 1109 | |
| 1110 class MarkCompactMarkingVisitor | 1086 class MarkCompactMarkingVisitor |
| 1111 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { | 1087 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { |
| 1112 public: | 1088 public: |
| 1113 static void Initialize(); | 1089 static void Initialize(); |
| 1114 | 1090 |
| 1115 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) { | 1091 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) { |
| 1116 MarkObjectByPointer(heap->mark_compact_collector(), object, p); | 1092 MarkObjectByPointer(heap->mark_compact_collector(), object, p); |
| 1117 } | 1093 } |
| 1118 | 1094 |
| 1119 INLINE(static void VisitPointers(Heap* heap, HeapObject* object, | 1095 INLINE(static void VisitPointers(Heap* heap, HeapObject* object, |
| (...skipping 2955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4075 } | 4051 } |
| 4076 | 4052 |
| 4077 | 4053 |
| 4078 void MarkCompactCollector::ParallelSweepSpacesComplete() { | 4054 void MarkCompactCollector::ParallelSweepSpacesComplete() { |
| 4079 ParallelSweepSpaceComplete(heap()->old_space()); | 4055 ParallelSweepSpaceComplete(heap()->old_space()); |
| 4080 ParallelSweepSpaceComplete(heap()->code_space()); | 4056 ParallelSweepSpaceComplete(heap()->code_space()); |
| 4081 ParallelSweepSpaceComplete(heap()->map_space()); | 4057 ParallelSweepSpaceComplete(heap()->map_space()); |
| 4082 } | 4058 } |
| 4083 | 4059 |
| 4084 | 4060 |
| 4085 void MarkCompactCollector::EnableCodeFlushing(bool enable) { | |
| 4086 if (isolate()->debug()->is_active()) enable = false; | |
| 4087 | |
| 4088 if (enable) { | |
| 4089 if (code_flusher_ != NULL) return; | |
| 4090 code_flusher_ = new CodeFlusher(isolate()); | |
| 4091 } else { | |
| 4092 if (code_flusher_ == NULL) return; | |
| 4093 code_flusher_->EvictAllCandidates(); | |
| 4094 delete code_flusher_; | |
| 4095 code_flusher_ = NULL; | |
| 4096 } | |
| 4097 | |
| 4098 if (FLAG_trace_code_flushing) { | |
| 4099 PrintF("[code-flushing is now %s]\n", enable ? "on" : "off"); | |
| 4100 } | |
| 4101 } | |
| 4102 | |
| 4103 | |
| 4104 // TODO(1466) ReportDeleteIfNeeded is not called currently. | 4061 // TODO(1466) ReportDeleteIfNeeded is not called currently. |
| 4105 // Our profiling tools do not expect intersections between | 4062 // Our profiling tools do not expect intersections between |
| 4106 // code objects. We should either reenable it or change our tools. | 4063 // code objects. We should either reenable it or change our tools. |
| 4107 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj, | 4064 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj, |
| 4108 Isolate* isolate) { | 4065 Isolate* isolate) { |
| 4109 if (obj->IsCode()) { | 4066 if (obj->IsCode()) { |
| 4110 PROFILE(isolate, CodeDeleteEvent(obj->address())); | 4067 PROFILE(isolate, CodeDeleteEvent(obj->address())); |
| 4111 } | 4068 } |
| 4112 } | 4069 } |
| 4113 | 4070 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4168 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4125 MarkBit mark_bit = Marking::MarkBitFrom(host); |
| 4169 if (Marking::IsBlack(mark_bit)) { | 4126 if (Marking::IsBlack(mark_bit)) { |
| 4170 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 4127 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
| 4171 RecordRelocSlot(&rinfo, target); | 4128 RecordRelocSlot(&rinfo, target); |
| 4172 } | 4129 } |
| 4173 } | 4130 } |
| 4174 } | 4131 } |
| 4175 | 4132 |
| 4176 } // namespace internal | 4133 } // namespace internal |
| 4177 } // namespace v8 | 4134 } // namespace v8 |
| OLD | NEW |