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