Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Side by Side Diff: src/heap/mark-compact.cc

Issue 2863703004: [heap] Reland "Make non-atomic markbit operations consistent with atomic ones." (Closed)
Patch Set: fix dcheck Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 if (MarkRecursively(heap, target_object)) return; 1189 if (MarkRecursively(heap, target_object)) return;
1190 heap->minor_mark_compact_collector()->MarkObject(target_object); 1190 heap->minor_mark_compact_collector()->MarkObject(target_object);
1191 } 1191 }
1192 } 1192 }
1193 1193
1194 protected: 1194 protected:
1195 inline static bool MarkRecursively(Heap* heap, HeapObject* object) { 1195 inline static bool MarkRecursively(Heap* heap, HeapObject* object) {
1196 StackLimitCheck check(heap->isolate()); 1196 StackLimitCheck check(heap->isolate());
1197 if (check.HasOverflowed()) return false; 1197 if (check.HasOverflowed()) return false;
1198 1198
1199 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( 1199 if (ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>(
1200 object, MarkingState::External(object))) 1200 object, MarkingState::External(object))) {
1201 return true; 1201 IterateBody(object->map(), object);
1202 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( 1202 }
1203 object, MarkingState::External(object));
1204 IterateBody(object->map(), object);
1205 return true; 1203 return true;
1206 } 1204 }
1207 }; 1205 };
1208 1206
1209 class MarkCompactMarkingVisitor 1207 class MarkCompactMarkingVisitor
1210 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { 1208 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> {
1211 public: 1209 public:
1212 static void Initialize(); 1210 static void Initialize();
1213 1211
1214 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) { 1212 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) {
(...skipping 15 matching lines...) Expand all
1230 } 1228 }
1231 1229
1232 // Marks the object black and pushes it on the marking stack. 1230 // Marks the object black and pushes it on the marking stack.
1233 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) { 1231 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) {
1234 heap->mark_compact_collector()->MarkObject(object); 1232 heap->mark_compact_collector()->MarkObject(object);
1235 } 1233 }
1236 1234
1237 // Marks the object black without pushing it on the marking stack. 1235 // Marks the object black without pushing it on the marking stack.
1238 // Returns true if object needed marking and false otherwise. 1236 // Returns true if object needed marking and false otherwise.
1239 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) { 1237 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) {
1240 if (ObjectMarking::IsWhite(object, MarkingState::Internal(object))) { 1238 return ObjectMarking::WhiteToBlack(object, MarkingState::Internal(object));
1241 ObjectMarking::WhiteToBlack(object, MarkingState::Internal(object));
1242 return true;
1243 }
1244 return false;
1245 } 1239 }
1246 1240
1247 // Mark object pointed to by p. 1241 // Mark object pointed to by p.
1248 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, 1242 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector,
1249 HeapObject* object, Object** p)) { 1243 HeapObject* object, Object** p)) {
1250 if (!(*p)->IsHeapObject()) return; 1244 if (!(*p)->IsHeapObject()) return;
1251 HeapObject* target_object = HeapObject::cast(*p); 1245 HeapObject* target_object = HeapObject::cast(*p);
1252 collector->RecordSlot(object, p, target_object); 1246 collector->RecordSlot(object, p, target_object);
1253 collector->MarkObject(target_object); 1247 collector->MarkObject(target_object);
1254 } 1248 }
1255 1249
1256 1250
1257 // Visit an unmarked object. 1251 // Visit an unmarked object.
1258 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, 1252 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector,
1259 HeapObject* obj)) { 1253 HeapObject* obj)) {
1260 #ifdef DEBUG 1254 #ifdef DEBUG
1261 DCHECK(collector->heap()->Contains(obj)); 1255 DCHECK(collector->heap()->Contains(obj));
1262 DCHECK(ObjectMarking::IsWhite(obj, MarkingState::Internal(obj)));
1263 #endif 1256 #endif
1264 Map* map = obj->map(); 1257 if (ObjectMarking::WhiteToBlack(obj, MarkingState::Internal(obj))) {
1265 Heap* heap = obj->GetHeap(); 1258 Map* map = obj->map();
1266 ObjectMarking::WhiteToBlack(obj, MarkingState::Internal(obj)); 1259 Heap* heap = obj->GetHeap();
1267 // Mark the map pointer and the body. 1260 ObjectMarking::WhiteToBlack(obj, MarkingState::Internal(obj));
1268 heap->mark_compact_collector()->MarkObject(map); 1261 // Mark the map pointer and the body.
1269 IterateBody(map, obj); 1262 heap->mark_compact_collector()->MarkObject(map);
1263 IterateBody(map, obj);
1264 }
1270 } 1265 }
1271 1266
1272 // Visit all unmarked objects pointed to by [start, end). 1267 // Visit all unmarked objects pointed to by [start, end).
1273 // Returns false if the operation fails (lack of stack space). 1268 // Returns false if the operation fails (lack of stack space).
1274 INLINE(static bool VisitUnmarkedObjects(Heap* heap, HeapObject* object, 1269 INLINE(static bool VisitUnmarkedObjects(Heap* heap, HeapObject* object,
1275 Object** start, Object** end)) { 1270 Object** start, Object** end)) {
1276 // Return false is we are close to the stack limit. 1271 // Return false is we are close to the stack limit.
1277 StackLimitCheck check(heap->isolate()); 1272 StackLimitCheck check(heap->isolate());
1278 if (check.HasOverflowed()) return false; 1273 if (check.HasOverflowed()) return false;
1279 1274
1280 MarkCompactCollector* collector = heap->mark_compact_collector(); 1275 MarkCompactCollector* collector = heap->mark_compact_collector();
1281 // Visit the unmarked objects. 1276 // Visit the unmarked objects.
1282 for (Object** p = start; p < end; p++) { 1277 for (Object** p = start; p < end; p++) {
1283 Object* o = *p; 1278 Object* o = *p;
1284 if (!o->IsHeapObject()) continue; 1279 if (!o->IsHeapObject()) continue;
1285 collector->RecordSlot(object, p, o); 1280 collector->RecordSlot(object, p, o);
1286 HeapObject* obj = HeapObject::cast(o); 1281 HeapObject* obj = HeapObject::cast(o);
1287 if (ObjectMarking::IsBlackOrGrey(obj, MarkingState::Internal(obj)))
1288 continue;
1289 VisitUnmarkedObject(collector, obj); 1282 VisitUnmarkedObject(collector, obj);
1290 } 1283 }
1291 return true; 1284 return true;
1292 } 1285 }
1293 1286
1294 private: 1287 private:
1295 // Code flushing support. 1288 // Code flushing support.
1296 1289
1297 static const int kRegExpCodeThreshold = 5; 1290 static const int kRegExpCodeThreshold = 5;
1298 1291
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 } 1468 }
1476 1469
1477 private: 1470 private:
1478 void MarkObjectByPointer(Object** p) { 1471 void MarkObjectByPointer(Object** p) {
1479 if (!(*p)->IsHeapObject()) return; 1472 if (!(*p)->IsHeapObject()) return;
1480 1473
1481 HeapObject* object = HeapObject::cast(*p); 1474 HeapObject* object = HeapObject::cast(*p);
1482 1475
1483 if (!collector_->heap()->InNewSpace(object)) return; 1476 if (!collector_->heap()->InNewSpace(object)) return;
1484 1477
1485 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( 1478 if (ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>(
1486 object, MarkingState::External(object))) 1479 object, MarkingState::External(object))) {
1487 return; 1480 Map* map = object->map();
1488 1481 StaticYoungGenerationMarkingVisitor::IterateBody(map, object);
1489 Map* map = object->map(); 1482 collector_->EmptyMarkingDeque();
1490 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( 1483 }
1491 object, MarkingState::External(object));
1492 StaticYoungGenerationMarkingVisitor::IterateBody(map, object);
1493
1494 collector_->EmptyMarkingDeque();
1495 } 1484 }
1496 1485
1497 MinorMarkCompactCollector* collector_; 1486 MinorMarkCompactCollector* collector_;
1498 }; 1487 };
1499 1488
1500 // Visitor class for marking heap roots. 1489 // Visitor class for marking heap roots.
1501 // TODO(ulan): Remove ObjectVisitor base class after fixing marking of 1490 // TODO(ulan): Remove ObjectVisitor base class after fixing marking of
1502 // the string table and the top optimized code. 1491 // the string table and the top optimized code.
1503 class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor, 1492 class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor,
1504 public RootVisitor { 1493 public RootVisitor {
(...skipping 20 matching lines...) Expand all
1525 // Skip the weak next code link in a code object, which is visited in 1514 // Skip the weak next code link in a code object, which is visited in
1526 // ProcessTopOptimizedFrame. 1515 // ProcessTopOptimizedFrame.
1527 void VisitNextCodeLink(Code* host, Object** p) override {} 1516 void VisitNextCodeLink(Code* host, Object** p) override {}
1528 1517
1529 private: 1518 private:
1530 void MarkObjectByPointer(Object** p) { 1519 void MarkObjectByPointer(Object** p) {
1531 if (!(*p)->IsHeapObject()) return; 1520 if (!(*p)->IsHeapObject()) return;
1532 1521
1533 HeapObject* object = HeapObject::cast(*p); 1522 HeapObject* object = HeapObject::cast(*p);
1534 1523
1535 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( 1524 if (ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>(
1536 object, MarkingState::Internal(object))) 1525 object, MarkingState::Internal(object))) {
1537 return; 1526 Map* map = object->map();
1538 1527 // Mark the map pointer and body, and push them on the marking stack.
1539 Map* map = object->map(); 1528 collector_->MarkObject(map);
1540 // Mark the object. 1529 MarkCompactMarkingVisitor::IterateBody(map, object);
1541 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( 1530 // Mark all the objects reachable from the map and body. May leave
1542 object, MarkingState::Internal(object)); 1531 // overflowed objects in the heap.
1543 1532 collector_->EmptyMarkingDeque();
1544 // Mark the map pointer and body, and push them on the marking stack. 1533 }
1545 collector_->MarkObject(map);
1546 MarkCompactMarkingVisitor::IterateBody(map, object);
1547
1548 // Mark all the objects reachable from the map and body. May leave
1549 // overflowed objects in the heap.
1550 collector_->EmptyMarkingDeque();
1551 } 1534 }
1552 1535
1553 MarkCompactCollector* collector_; 1536 MarkCompactCollector* collector_;
1554 }; 1537 };
1555 1538
1556 class InternalizedStringTableCleaner : public ObjectVisitor { 1539 class InternalizedStringTableCleaner : public ObjectVisitor {
1557 public: 1540 public:
1558 InternalizedStringTableCleaner(Heap* heap, HeapObject* table) 1541 InternalizedStringTableCleaner(Heap* heap, HeapObject* table)
1559 : heap_(heap), pointers_removed_(0), table_(table) {} 1542 : heap_(heap), pointers_removed_(0), table_(table) {}
1560 1543
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 // is reached, whichever comes first. 1694 // is reached, whichever comes first.
1712 template <class T> 1695 template <class T>
1713 void MarkCompactCollector::DiscoverGreyObjectsWithIterator(T* it) { 1696 void MarkCompactCollector::DiscoverGreyObjectsWithIterator(T* it) {
1714 // The caller should ensure that the marking stack is initially not full, 1697 // The caller should ensure that the marking stack is initially not full,
1715 // so that we don't waste effort pointlessly scanning for objects. 1698 // so that we don't waste effort pointlessly scanning for objects.
1716 DCHECK(!marking_deque()->IsFull()); 1699 DCHECK(!marking_deque()->IsFull());
1717 1700
1718 Map* filler_map = heap()->one_pointer_filler_map(); 1701 Map* filler_map = heap()->one_pointer_filler_map();
1719 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) { 1702 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) {
1720 if ((object->map() != filler_map) && 1703 if ((object->map() != filler_map) &&
1721 ObjectMarking::IsGrey(object, MarkingState::Internal(object))) { 1704 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object))) {
1722 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object));
1723 PushBlack(object); 1705 PushBlack(object);
1724 if (marking_deque()->IsFull()) return; 1706 if (marking_deque()->IsFull()) return;
1725 } 1707 }
1726 } 1708 }
1727 } 1709 }
1728 1710
1729 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) { 1711 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) {
1730 DCHECK(!marking_deque()->IsFull()); 1712 DCHECK(!marking_deque()->IsFull());
1731 LiveObjectIterator<kGreyObjects> it(p, MarkingState::Internal(p)); 1713 LiveObjectIterator<kGreyObjects> it(p, MarkingState::Internal(p));
1732 HeapObject* object = NULL; 1714 HeapObject* object = NULL;
1733 while ((object = it.Next()) != NULL) { 1715 while ((object = it.Next()) != NULL) {
1734 DCHECK(ObjectMarking::IsGrey(object, MarkingState::Internal(object))); 1716 bool success =
1735 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object)); 1717 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object));
1718 DCHECK(success);
1719 USE(success);
1736 PushBlack(object); 1720 PushBlack(object);
1737 if (marking_deque()->IsFull()) return; 1721 if (marking_deque()->IsFull()) return;
1738 } 1722 }
1739 } 1723 }
1740 1724
1741 class RecordMigratedSlotVisitor : public ObjectVisitor { 1725 class RecordMigratedSlotVisitor : public ObjectVisitor {
1742 public: 1726 public:
1743 explicit RecordMigratedSlotVisitor(MarkCompactCollector* collector) 1727 explicit RecordMigratedSlotVisitor(MarkCompactCollector* collector)
1744 : collector_(collector) {} 1728 : collector_(collector) {}
1745 1729
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 2272 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
2289 Object* o = *p; 2273 Object* o = *p;
2290 if (!o->IsHeapObject()) return false; 2274 if (!o->IsHeapObject()) return false;
2291 return ObjectMarking::IsWhite(HeapObject::cast(o), 2275 return ObjectMarking::IsWhite(HeapObject::cast(o),
2292 MarkingState::Internal(HeapObject::cast(o))); 2276 MarkingState::Internal(HeapObject::cast(o)));
2293 } 2277 }
2294 2278
2295 void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) { 2279 void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) {
2296 StringTable* string_table = heap()->string_table(); 2280 StringTable* string_table = heap()->string_table();
2297 // Mark the string table itself. 2281 // Mark the string table itself.
2298 if (ObjectMarking::IsWhite(string_table, 2282 if (ObjectMarking::WhiteToBlack(string_table,
2299 MarkingState::Internal(string_table))) { 2283 MarkingState::Internal(string_table))) {
2300 // String table could have already been marked by visiting the handles list. 2284 // Explicitly mark the prefix.
2301 ObjectMarking::WhiteToBlack(string_table, 2285 string_table->IteratePrefix(visitor);
2302 MarkingState::Internal(string_table)); 2286 ProcessMarkingDeque();
2303 } 2287 }
2304 // Explicitly mark the prefix.
2305 string_table->IteratePrefix(visitor);
2306 ProcessMarkingDeque();
2307 } 2288 }
2308 2289
2309 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { 2290 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
2310 // Mark the heap roots including global variables, stack variables, 2291 // Mark the heap roots including global variables, stack variables,
2311 // etc., and all objects reachable from them. 2292 // etc., and all objects reachable from them.
2312 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); 2293 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
2313 2294
2314 // Handle the string table specially. 2295 // Handle the string table specially.
2315 MarkStringTable(visitor); 2296 MarkStringTable(visitor);
2316 2297
(...skipping 2223 matching lines...) Expand 10 before | Expand all | Expand 10 after
4540 // The target is always in old space, we don't have to record the slot in 4521 // The target is always in old space, we don't have to record the slot in
4541 // the old-to-new remembered set. 4522 // the old-to-new remembered set.
4542 DCHECK(!heap()->InNewSpace(target)); 4523 DCHECK(!heap()->InNewSpace(target));
4543 RecordRelocSlot(host, &rinfo, target); 4524 RecordRelocSlot(host, &rinfo, target);
4544 } 4525 }
4545 } 4526 }
4546 } 4527 }
4547 4528
4548 } // namespace internal 4529 } // namespace internal
4549 } // namespace v8 4530 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698