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 |