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

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

Issue 2857713002: [heap] Make non-atomic markbit operations consistent with atomic ones. (Closed)
Patch Set: fix overlap check 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 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 if (MarkRecursively(heap, target_object)) return; 1169 if (MarkRecursively(heap, target_object)) return;
1170 heap->minor_mark_compact_collector()->MarkObject(target_object); 1170 heap->minor_mark_compact_collector()->MarkObject(target_object);
1171 } 1171 }
1172 } 1172 }
1173 1173
1174 protected: 1174 protected:
1175 inline static bool MarkRecursively(Heap* heap, HeapObject* object) { 1175 inline static bool MarkRecursively(Heap* heap, HeapObject* object) {
1176 StackLimitCheck check(heap->isolate()); 1176 StackLimitCheck check(heap->isolate());
1177 if (check.HasOverflowed()) return false; 1177 if (check.HasOverflowed()) return false;
1178 1178
1179 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( 1179 if (ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>(
1180 object, MarkingState::External(object))) 1180 object, MarkingState::External(object))) {
1181 return true; 1181 IterateBody(object->map(), object);
1182 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( 1182 }
1183 object, MarkingState::External(object));
1184 IterateBody(object->map(), object);
1185 return true; 1183 return true;
1186 } 1184 }
1187 }; 1185 };
1188 1186
1189 class MarkCompactMarkingVisitor 1187 class MarkCompactMarkingVisitor
1190 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { 1188 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> {
1191 public: 1189 public:
1192 static void Initialize(); 1190 static void Initialize();
1193 1191
1194 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) { 1192 INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) {
(...skipping 15 matching lines...) Expand all
1210 } 1208 }
1211 1209
1212 // Marks the object black and pushes it on the marking stack. 1210 // Marks the object black and pushes it on the marking stack.
1213 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) { 1211 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) {
1214 heap->mark_compact_collector()->MarkObject(object); 1212 heap->mark_compact_collector()->MarkObject(object);
1215 } 1213 }
1216 1214
1217 // Marks the object black without pushing it on the marking stack. 1215 // Marks the object black without pushing it on the marking stack.
1218 // Returns true if object needed marking and false otherwise. 1216 // Returns true if object needed marking and false otherwise.
1219 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) { 1217 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) {
1220 if (ObjectMarking::IsWhite(object, MarkingState::Internal(object))) { 1218 return ObjectMarking::WhiteToBlack(object, MarkingState::Internal(object));
1221 ObjectMarking::WhiteToBlack(object, MarkingState::Internal(object));
1222 return true;
1223 }
1224 return false;
1225 } 1219 }
1226 1220
1227 // Mark object pointed to by p. 1221 // Mark object pointed to by p.
1228 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, 1222 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector,
1229 HeapObject* object, Object** p)) { 1223 HeapObject* object, Object** p)) {
1230 if (!(*p)->IsHeapObject()) return; 1224 if (!(*p)->IsHeapObject()) return;
1231 HeapObject* target_object = HeapObject::cast(*p); 1225 HeapObject* target_object = HeapObject::cast(*p);
1232 collector->RecordSlot(object, p, target_object); 1226 collector->RecordSlot(object, p, target_object);
1233 collector->MarkObject(target_object); 1227 collector->MarkObject(target_object);
1234 } 1228 }
1235 1229
1236 1230
1237 // Visit an unmarked object. 1231 // Visit an unmarked object.
1238 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, 1232 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector,
1239 HeapObject* obj)) { 1233 HeapObject* obj)) {
1240 #ifdef DEBUG 1234 #ifdef DEBUG
1241 DCHECK(collector->heap()->Contains(obj)); 1235 DCHECK(collector->heap()->Contains(obj));
1242 DCHECK(ObjectMarking::IsWhite(obj, MarkingState::Internal(obj)));
1243 #endif 1236 #endif
1244 Map* map = obj->map(); 1237 if (ObjectMarking::WhiteToBlack(obj, MarkingState::Internal(obj))) {
1245 Heap* heap = obj->GetHeap(); 1238 Map* map = obj->map();
1246 ObjectMarking::WhiteToBlack(obj, MarkingState::Internal(obj)); 1239 Heap* heap = obj->GetHeap();
1247 // Mark the map pointer and the body. 1240 ObjectMarking::WhiteToBlack(obj, MarkingState::Internal(obj));
1248 heap->mark_compact_collector()->MarkObject(map); 1241 // Mark the map pointer and the body.
1249 IterateBody(map, obj); 1242 heap->mark_compact_collector()->MarkObject(map);
1243 IterateBody(map, obj);
1244 }
1250 } 1245 }
1251 1246
1252 // Visit all unmarked objects pointed to by [start, end). 1247 // Visit all unmarked objects pointed to by [start, end).
1253 // Returns false if the operation fails (lack of stack space). 1248 // Returns false if the operation fails (lack of stack space).
1254 INLINE(static bool VisitUnmarkedObjects(Heap* heap, HeapObject* object, 1249 INLINE(static bool VisitUnmarkedObjects(Heap* heap, HeapObject* object,
1255 Object** start, Object** end)) { 1250 Object** start, Object** end)) {
1256 // Return false is we are close to the stack limit. 1251 // Return false is we are close to the stack limit.
1257 StackLimitCheck check(heap->isolate()); 1252 StackLimitCheck check(heap->isolate());
1258 if (check.HasOverflowed()) return false; 1253 if (check.HasOverflowed()) return false;
1259 1254
1260 MarkCompactCollector* collector = heap->mark_compact_collector(); 1255 MarkCompactCollector* collector = heap->mark_compact_collector();
1261 // Visit the unmarked objects. 1256 // Visit the unmarked objects.
1262 for (Object** p = start; p < end; p++) { 1257 for (Object** p = start; p < end; p++) {
1263 Object* o = *p; 1258 Object* o = *p;
1264 if (!o->IsHeapObject()) continue; 1259 if (!o->IsHeapObject()) continue;
1265 collector->RecordSlot(object, p, o); 1260 collector->RecordSlot(object, p, o);
1266 HeapObject* obj = HeapObject::cast(o); 1261 HeapObject* obj = HeapObject::cast(o);
1267 if (ObjectMarking::IsBlackOrGrey(obj, MarkingState::Internal(obj)))
1268 continue;
1269 VisitUnmarkedObject(collector, obj); 1262 VisitUnmarkedObject(collector, obj);
1270 } 1263 }
1271 return true; 1264 return true;
1272 } 1265 }
1273 1266
1274 private: 1267 private:
1275 // Code flushing support. 1268 // Code flushing support.
1276 1269
1277 static const int kRegExpCodeThreshold = 5; 1270 static const int kRegExpCodeThreshold = 5;
1278 1271
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 } 1448 }
1456 1449
1457 private: 1450 private:
1458 void MarkObjectByPointer(Object** p) { 1451 void MarkObjectByPointer(Object** p) {
1459 if (!(*p)->IsHeapObject()) return; 1452 if (!(*p)->IsHeapObject()) return;
1460 1453
1461 HeapObject* object = HeapObject::cast(*p); 1454 HeapObject* object = HeapObject::cast(*p);
1462 1455
1463 if (!collector_->heap()->InNewSpace(object)) return; 1456 if (!collector_->heap()->InNewSpace(object)) return;
1464 1457
1465 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( 1458 if (ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>(
1466 object, MarkingState::External(object))) 1459 object, MarkingState::External(object))) {
1467 return; 1460 Map* map = object->map();
1468 1461 StaticYoungGenerationMarkingVisitor::IterateBody(map, object);
1469 Map* map = object->map(); 1462 collector_->EmptyMarkingDeque();
1470 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( 1463 }
1471 object, MarkingState::External(object));
1472 StaticYoungGenerationMarkingVisitor::IterateBody(map, object);
1473
1474 collector_->EmptyMarkingDeque();
1475 } 1464 }
1476 1465
1477 MinorMarkCompactCollector* collector_; 1466 MinorMarkCompactCollector* collector_;
1478 }; 1467 };
1479 1468
1480 // Visitor class for marking heap roots. 1469 // Visitor class for marking heap roots.
1481 // TODO(ulan): Remove ObjectVisitor base class after fixing marking of 1470 // TODO(ulan): Remove ObjectVisitor base class after fixing marking of
1482 // the string table and the top optimized code. 1471 // the string table and the top optimized code.
1483 class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor, 1472 class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor,
1484 public RootVisitor { 1473 public RootVisitor {
(...skipping 20 matching lines...) Expand all
1505 // Skip the weak next code link in a code object, which is visited in 1494 // Skip the weak next code link in a code object, which is visited in
1506 // ProcessTopOptimizedFrame. 1495 // ProcessTopOptimizedFrame.
1507 void VisitNextCodeLink(Code* host, Object** p) override {} 1496 void VisitNextCodeLink(Code* host, Object** p) override {}
1508 1497
1509 private: 1498 private:
1510 void MarkObjectByPointer(Object** p) { 1499 void MarkObjectByPointer(Object** p) {
1511 if (!(*p)->IsHeapObject()) return; 1500 if (!(*p)->IsHeapObject()) return;
1512 1501
1513 HeapObject* object = HeapObject::cast(*p); 1502 HeapObject* object = HeapObject::cast(*p);
1514 1503
1515 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( 1504 if (ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>(
1516 object, MarkingState::Internal(object))) 1505 object, MarkingState::Internal(object))) {
1517 return; 1506 Map* map = object->map();
1518 1507 // Mark the map pointer and body, and push them on the marking stack.
1519 Map* map = object->map(); 1508 collector_->MarkObject(map);
1520 // Mark the object. 1509 MarkCompactMarkingVisitor::IterateBody(map, object);
1521 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( 1510 // Mark all the objects reachable from the map and body. May leave
1522 object, MarkingState::Internal(object)); 1511 // overflowed objects in the heap.
1523 1512 collector_->EmptyMarkingDeque();
1524 // Mark the map pointer and body, and push them on the marking stack. 1513 }
1525 collector_->MarkObject(map);
1526 MarkCompactMarkingVisitor::IterateBody(map, object);
1527
1528 // Mark all the objects reachable from the map and body. May leave
1529 // overflowed objects in the heap.
1530 collector_->EmptyMarkingDeque();
1531 } 1514 }
1532 1515
1533 MarkCompactCollector* collector_; 1516 MarkCompactCollector* collector_;
1534 }; 1517 };
1535 1518
1536 class InternalizedStringTableCleaner : public ObjectVisitor { 1519 class InternalizedStringTableCleaner : public ObjectVisitor {
1537 public: 1520 public:
1538 InternalizedStringTableCleaner(Heap* heap, HeapObject* table) 1521 InternalizedStringTableCleaner(Heap* heap, HeapObject* table)
1539 : heap_(heap), pointers_removed_(0), table_(table) {} 1522 : heap_(heap), pointers_removed_(0), table_(table) {}
1540 1523
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 // is reached, whichever comes first. 1614 // is reached, whichever comes first.
1632 template <class T> 1615 template <class T>
1633 void MarkCompactCollector::DiscoverGreyObjectsWithIterator(T* it) { 1616 void MarkCompactCollector::DiscoverGreyObjectsWithIterator(T* it) {
1634 // The caller should ensure that the marking stack is initially not full, 1617 // The caller should ensure that the marking stack is initially not full,
1635 // so that we don't waste effort pointlessly scanning for objects. 1618 // so that we don't waste effort pointlessly scanning for objects.
1636 DCHECK(!marking_deque()->IsFull()); 1619 DCHECK(!marking_deque()->IsFull());
1637 1620
1638 Map* filler_map = heap()->one_pointer_filler_map(); 1621 Map* filler_map = heap()->one_pointer_filler_map();
1639 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) { 1622 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) {
1640 if ((object->map() != filler_map) && 1623 if ((object->map() != filler_map) &&
1641 ObjectMarking::IsGrey(object, MarkingState::Internal(object))) { 1624 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object))) {
1642 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object));
1643 PushBlack(object); 1625 PushBlack(object);
1644 if (marking_deque()->IsFull()) return; 1626 if (marking_deque()->IsFull()) return;
1645 } 1627 }
1646 } 1628 }
1647 } 1629 }
1648 1630
1649 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) { 1631 void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) {
1650 DCHECK(!marking_deque()->IsFull()); 1632 DCHECK(!marking_deque()->IsFull());
1651 LiveObjectIterator<kGreyObjects> it(p, MarkingState::Internal(p)); 1633 LiveObjectIterator<kGreyObjects> it(p, MarkingState::Internal(p));
1652 HeapObject* object = NULL; 1634 HeapObject* object = NULL;
1653 while ((object = it.Next()) != NULL) { 1635 while ((object = it.Next()) != NULL) {
1654 DCHECK(ObjectMarking::IsGrey(object, MarkingState::Internal(object))); 1636 bool success =
1655 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object)); 1637 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object));
1638 DCHECK(success);
1639 USE(success);
1656 PushBlack(object); 1640 PushBlack(object);
1657 if (marking_deque()->IsFull()) return; 1641 if (marking_deque()->IsFull()) return;
1658 } 1642 }
1659 } 1643 }
1660 1644
1661 class RecordMigratedSlotVisitor : public ObjectVisitor { 1645 class RecordMigratedSlotVisitor : public ObjectVisitor {
1662 public: 1646 public:
1663 explicit RecordMigratedSlotVisitor(MarkCompactCollector* collector) 1647 explicit RecordMigratedSlotVisitor(MarkCompactCollector* collector)
1664 : collector_(collector) {} 1648 : collector_(collector) {}
1665 1649
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
2139 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 2123 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
2140 Object* o = *p; 2124 Object* o = *p;
2141 if (!o->IsHeapObject()) return false; 2125 if (!o->IsHeapObject()) return false;
2142 return ObjectMarking::IsWhite(HeapObject::cast(o), 2126 return ObjectMarking::IsWhite(HeapObject::cast(o),
2143 MarkingState::Internal(HeapObject::cast(o))); 2127 MarkingState::Internal(HeapObject::cast(o)));
2144 } 2128 }
2145 2129
2146 void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) { 2130 void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) {
2147 StringTable* string_table = heap()->string_table(); 2131 StringTable* string_table = heap()->string_table();
2148 // Mark the string table itself. 2132 // Mark the string table itself.
2149 if (ObjectMarking::IsWhite(string_table, 2133 if (ObjectMarking::WhiteToBlack(string_table,
2150 MarkingState::Internal(string_table))) { 2134 MarkingState::Internal(string_table))) {
2151 // String table could have already been marked by visiting the handles list. 2135 // Explicitly mark the prefix.
2152 ObjectMarking::WhiteToBlack(string_table, 2136 string_table->IteratePrefix(visitor);
2153 MarkingState::Internal(string_table)); 2137 ProcessMarkingDeque();
2154 } 2138 }
2155 // Explicitly mark the prefix.
2156 string_table->IteratePrefix(visitor);
2157 ProcessMarkingDeque();
2158 } 2139 }
2159 2140
2160 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { 2141 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
2161 // Mark the heap roots including global variables, stack variables, 2142 // Mark the heap roots including global variables, stack variables,
2162 // etc., and all objects reachable from them. 2143 // etc., and all objects reachable from them.
2163 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); 2144 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
2164 2145
2165 // Handle the string table specially. 2146 // Handle the string table specially.
2166 MarkStringTable(visitor); 2147 MarkStringTable(visitor);
2167 2148
(...skipping 2018 matching lines...) Expand 10 before | Expand all | Expand 10 after
4186 // The target is always in old space, we don't have to record the slot in 4167 // The target is always in old space, we don't have to record the slot in
4187 // the old-to-new remembered set. 4168 // the old-to-new remembered set.
4188 DCHECK(!heap()->InNewSpace(target)); 4169 DCHECK(!heap()->InNewSpace(target));
4189 RecordRelocSlot(host, &rinfo, target); 4170 RecordRelocSlot(host, &rinfo, target);
4190 } 4171 }
4191 } 4172 }
4192 } 4173 }
4193 4174
4194 } // namespace internal 4175 } // namespace internal
4195 } // namespace v8 4176 } // 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