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 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 heap->mark_compact_collector()->MarkObject<MarkingMode::YOUNG_GENERATION>( | 1080 heap->mark_compact_collector()->MarkObject<MarkingMode::YOUNG_GENERATION>( |
1081 HeapObject::cast(target)); | 1081 HeapObject::cast(target)); |
1082 } | 1082 } |
1083 } | 1083 } |
1084 | 1084 |
1085 protected: | 1085 protected: |
1086 inline static bool MarkRecursively(Heap* heap, HeapObject* object) { | 1086 inline static bool MarkRecursively(Heap* heap, HeapObject* object) { |
1087 StackLimitCheck check(heap->isolate()); | 1087 StackLimitCheck check(heap->isolate()); |
1088 if (check.HasOverflowed()) return false; | 1088 if (check.HasOverflowed()) return false; |
1089 | 1089 |
1090 if (ObjectMarking::IsBlackOrGrey<MarkingMode::YOUNG_GENERATION>(object)) | 1090 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC, |
| 1091 MarkingMode::YOUNG_GENERATION>(object)) |
1091 return true; | 1092 return true; |
1092 ObjectMarking::WhiteToBlack<MarkingMode::YOUNG_GENERATION>(object); | 1093 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC, |
| 1094 MarkingMode::YOUNG_GENERATION>(object); |
1093 IterateBody(object->map(), object); | 1095 IterateBody(object->map(), object); |
1094 return true; | 1096 return true; |
1095 } | 1097 } |
1096 }; | 1098 }; |
1097 | 1099 |
1098 class MarkCompactMarkingVisitor | 1100 class MarkCompactMarkingVisitor |
1099 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { | 1101 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { |
1100 public: | 1102 public: |
1101 static void Initialize(); | 1103 static void Initialize(); |
1102 | 1104 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 private: | 1363 private: |
1362 void MarkObjectByPointer(Object** p) { | 1364 void MarkObjectByPointer(Object** p) { |
1363 if (!(*p)->IsHeapObject()) return; | 1365 if (!(*p)->IsHeapObject()) return; |
1364 | 1366 |
1365 HeapObject* object = HeapObject::cast(*p); | 1367 HeapObject* object = HeapObject::cast(*p); |
1366 | 1368 |
1367 if (mode == MarkingMode::YOUNG_GENERATION && | 1369 if (mode == MarkingMode::YOUNG_GENERATION && |
1368 !collector_->heap()->InNewSpace(object)) | 1370 !collector_->heap()->InNewSpace(object)) |
1369 return; | 1371 return; |
1370 | 1372 |
1371 if (ObjectMarking::IsBlackOrGrey<mode>(object)) return; | 1373 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC, mode>(object)) return; |
1372 | 1374 |
1373 Map* map = object->map(); | 1375 Map* map = object->map(); |
1374 // Mark the object. | 1376 // Mark the object. |
1375 ObjectMarking::WhiteToBlack<mode>(object); | 1377 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC, mode>(object); |
1376 | 1378 |
1377 switch (mode) { | 1379 switch (mode) { |
1378 case MarkingMode::FULL: { | 1380 case MarkingMode::FULL: { |
1379 // Mark the map pointer and body, and push them on the marking stack. | 1381 // Mark the map pointer and body, and push them on the marking stack. |
1380 collector_->MarkObject(map); | 1382 collector_->MarkObject(map); |
1381 MarkCompactMarkingVisitor::IterateBody(map, object); | 1383 MarkCompactMarkingVisitor::IterateBody(map, object); |
1382 } break; | 1384 } break; |
1383 case MarkingMode::YOUNG_GENERATION: | 1385 case MarkingMode::YOUNG_GENERATION: |
1384 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); | 1386 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); |
1385 break; | 1387 break; |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1980 // After: the marking stack is empty, and all objects reachable from the | 1982 // After: the marking stack is empty, and all objects reachable from the |
1981 // marking stack have been marked, or are overflowed in the heap. | 1983 // marking stack have been marked, or are overflowed in the heap. |
1982 template <MarkingMode mode> | 1984 template <MarkingMode mode> |
1983 void MarkCompactCollector::EmptyMarkingDeque() { | 1985 void MarkCompactCollector::EmptyMarkingDeque() { |
1984 while (!marking_deque<mode>()->IsEmpty()) { | 1986 while (!marking_deque<mode>()->IsEmpty()) { |
1985 HeapObject* object = marking_deque<mode>()->Pop(); | 1987 HeapObject* object = marking_deque<mode>()->Pop(); |
1986 | 1988 |
1987 DCHECK(!object->IsFiller()); | 1989 DCHECK(!object->IsFiller()); |
1988 DCHECK(object->IsHeapObject()); | 1990 DCHECK(object->IsHeapObject()); |
1989 DCHECK(heap()->Contains(object)); | 1991 DCHECK(heap()->Contains(object)); |
1990 DCHECK(!ObjectMarking::IsWhite<mode>(object)); | 1992 DCHECK(!(ObjectMarking::IsWhite<MarkBit::NON_ATOMIC, mode>(object))); |
1991 | 1993 |
1992 Map* map = object->map(); | 1994 Map* map = object->map(); |
1993 switch (mode) { | 1995 switch (mode) { |
1994 case MarkingMode::FULL: { | 1996 case MarkingMode::FULL: { |
1995 MarkObject(map); | 1997 MarkObject(map); |
1996 MarkCompactMarkingVisitor::IterateBody(map, object); | 1998 MarkCompactMarkingVisitor::IterateBody(map, object); |
1997 } break; | 1999 } break; |
1998 case MarkingMode::YOUNG_GENERATION: { | 2000 case MarkingMode::YOUNG_GENERATION: { |
1999 DCHECK(ObjectMarking::IsBlack<mode>(object)); | 2001 DCHECK((ObjectMarking::IsBlack<MarkBit::NON_ATOMIC, mode>(object))); |
2000 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); | 2002 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); |
2001 } break; | 2003 } break; |
2002 } | 2004 } |
2003 } | 2005 } |
2004 } | 2006 } |
2005 | 2007 |
2006 | 2008 |
2007 // Sweep the heap for overflowed objects, clear their overflow bits, and | 2009 // Sweep the heap for overflowed objects, clear their overflow bits, and |
2008 // push them on the marking stack. Stop early if the marking stack fills | 2010 // push them on the marking stack. Stop early if the marking stack fills |
2009 // before sweeping completes. If sweeping completes, there are no remaining | 2011 // before sweeping completes. If sweeping completes, there are no remaining |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2247 } | 2249 } |
2248 | 2250 |
2249 SlotCallbackResult MarkCompactCollector::CheckAndMarkObject( | 2251 SlotCallbackResult MarkCompactCollector::CheckAndMarkObject( |
2250 Heap* heap, Address slot_address) { | 2252 Heap* heap, Address slot_address) { |
2251 Object* object = *reinterpret_cast<Object**>(slot_address); | 2253 Object* object = *reinterpret_cast<Object**>(slot_address); |
2252 if (heap->InNewSpace(object)) { | 2254 if (heap->InNewSpace(object)) { |
2253 // Marking happens before flipping the young generation, so the object | 2255 // Marking happens before flipping the young generation, so the object |
2254 // has to be in ToSpace. | 2256 // has to be in ToSpace. |
2255 DCHECK(heap->InToSpace(object)); | 2257 DCHECK(heap->InToSpace(object)); |
2256 HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); | 2258 HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); |
2257 if (ObjectMarking::IsBlackOrGrey<MarkingMode::YOUNG_GENERATION>( | 2259 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC, |
| 2260 MarkingMode::YOUNG_GENERATION>( |
2258 heap_object)) { | 2261 heap_object)) { |
2259 return KEEP_SLOT; | 2262 return KEEP_SLOT; |
2260 } | 2263 } |
2261 ObjectMarking::WhiteToBlack<MarkingMode::YOUNG_GENERATION>(heap_object); | 2264 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC, |
| 2265 MarkingMode::YOUNG_GENERATION>(heap_object); |
2262 StaticYoungGenerationMarkingVisitor::IterateBody(heap_object->map(), | 2266 StaticYoungGenerationMarkingVisitor::IterateBody(heap_object->map(), |
2263 heap_object); | 2267 heap_object); |
2264 return KEEP_SLOT; | 2268 return KEEP_SLOT; |
2265 } | 2269 } |
2266 return REMOVE_SLOT; | 2270 return REMOVE_SLOT; |
2267 } | 2271 } |
2268 | 2272 |
2269 static bool IsUnmarkedObject(Heap* heap, Object** p) { | 2273 static bool IsUnmarkedObject(Heap* heap, Object** p) { |
2270 DCHECK_IMPLIES(heap->InNewSpace(*p), heap->InToSpace(*p)); | 2274 DCHECK_IMPLIES(heap->InNewSpace(*p), heap->InToSpace(*p)); |
2271 return heap->InNewSpace(*p) && !ObjectMarking::IsBlack(HeapObject::cast(*p)); | 2275 return heap->InNewSpace(*p) && !ObjectMarking::IsBlack(HeapObject::cast(*p)); |
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4007 // The target is always in old space, we don't have to record the slot in | 4011 // The target is always in old space, we don't have to record the slot in |
4008 // the old-to-new remembered set. | 4012 // the old-to-new remembered set. |
4009 DCHECK(!heap()->InNewSpace(target)); | 4013 DCHECK(!heap()->InNewSpace(target)); |
4010 RecordRelocSlot(host, &rinfo, target); | 4014 RecordRelocSlot(host, &rinfo, target); |
4011 } | 4015 } |
4012 } | 4016 } |
4013 } | 4017 } |
4014 | 4018 |
4015 } // namespace internal | 4019 } // namespace internal |
4016 } // namespace v8 | 4020 } // namespace v8 |
OLD | NEW |