OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 // Iterate the archived stacks in all threads to check if | 1171 // Iterate the archived stacks in all threads to check if |
1172 // the code is referenced. | 1172 // the code is referenced. |
1173 CodeMarkingVisitor code_marking_visitor(this); | 1173 CodeMarkingVisitor code_marking_visitor(this); |
1174 heap_->isolate()->thread_manager()->IterateArchivedThreads( | 1174 heap_->isolate()->thread_manager()->IterateArchivedThreads( |
1175 &code_marking_visitor); | 1175 &code_marking_visitor); |
1176 | 1176 |
1177 SharedFunctionInfoMarkingVisitor visitor(this); | 1177 SharedFunctionInfoMarkingVisitor visitor(this); |
1178 heap_->isolate()->compilation_cache()->IterateFunctions(&visitor); | 1178 heap_->isolate()->compilation_cache()->IterateFunctions(&visitor); |
1179 heap_->isolate()->handle_scope_implementer()->Iterate(&visitor); | 1179 heap_->isolate()->handle_scope_implementer()->Iterate(&visitor); |
1180 | 1180 |
1181 ProcessMarkingStack(); | 1181 ProcessMarkingDeque(); |
1182 } | 1182 } |
1183 | 1183 |
1184 | 1184 |
1185 // Visitor class for marking heap roots. | 1185 // Visitor class for marking heap roots. |
1186 class RootMarkingVisitor : public ObjectVisitor { | 1186 class RootMarkingVisitor : public ObjectVisitor { |
1187 public: | 1187 public: |
1188 explicit RootMarkingVisitor(Heap* heap) | 1188 explicit RootMarkingVisitor(Heap* heap) |
1189 : collector_(heap->mark_compact_collector()) { } | 1189 : collector_(heap->mark_compact_collector()) { } |
1190 | 1190 |
1191 void VisitPointer(Object** p) { | 1191 void VisitPointer(Object** p) { |
(...skipping 18 matching lines...) Expand all Loading... |
1210 // Mark the object. | 1210 // Mark the object. |
1211 HEAP->mark_compact_collector()->SetMark(object, mark_bit); | 1211 HEAP->mark_compact_collector()->SetMark(object, mark_bit); |
1212 | 1212 |
1213 // Mark the map pointer and body, and push them on the marking stack. | 1213 // Mark the map pointer and body, and push them on the marking stack. |
1214 MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 1214 MarkBit map_mark = Marking::MarkBitFromOldSpace(map); |
1215 HEAP->mark_compact_collector()->MarkObject(map, map_mark); | 1215 HEAP->mark_compact_collector()->MarkObject(map, map_mark); |
1216 StaticMarkingVisitor::IterateBody(map, object); | 1216 StaticMarkingVisitor::IterateBody(map, object); |
1217 | 1217 |
1218 // Mark all the objects reachable from the map and body. May leave | 1218 // Mark all the objects reachable from the map and body. May leave |
1219 // overflowed objects in the heap. | 1219 // overflowed objects in the heap. |
1220 collector_->EmptyMarkingStack(); | 1220 collector_->EmptyMarkingDeque(); |
1221 } | 1221 } |
1222 | 1222 |
1223 MarkCompactCollector* collector_; | 1223 MarkCompactCollector* collector_; |
1224 }; | 1224 }; |
1225 | 1225 |
1226 | 1226 |
1227 // Helper class for pruning the symbol table. | 1227 // Helper class for pruning the symbol table. |
1228 class SymbolTableCleaner : public ObjectVisitor { | 1228 class SymbolTableCleaner : public ObjectVisitor { |
1229 public: | 1229 public: |
1230 SymbolTableCleaner() : pointers_removed_(0) { } | 1230 SymbolTableCleaner() : pointers_removed_(0) { } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 if (object->IsMap()) { | 1280 if (object->IsMap()) { |
1281 Map* map = Map::cast(object); | 1281 Map* map = Map::cast(object); |
1282 if (FLAG_cleanup_caches_in_maps_at_gc) { | 1282 if (FLAG_cleanup_caches_in_maps_at_gc) { |
1283 map->ClearCodeCache(heap_); | 1283 map->ClearCodeCache(heap_); |
1284 } | 1284 } |
1285 if (FLAG_collect_maps && | 1285 if (FLAG_collect_maps && |
1286 map->instance_type() >= FIRST_JS_OBJECT_TYPE && | 1286 map->instance_type() >= FIRST_JS_OBJECT_TYPE && |
1287 map->instance_type() <= JS_FUNCTION_TYPE) { | 1287 map->instance_type() <= JS_FUNCTION_TYPE) { |
1288 MarkMapContents(map); | 1288 MarkMapContents(map); |
1289 } else { | 1289 } else { |
1290 marking_stack_.Push(map); | 1290 marking_deque_.Push(map); |
1291 } | 1291 } |
1292 } else { | 1292 } else { |
1293 marking_stack_.Push(object); | 1293 marking_deque_.Push(object); |
1294 } | 1294 } |
1295 } | 1295 } |
1296 | 1296 |
1297 | 1297 |
1298 void MarkCompactCollector::MarkMapContents(Map* map) { | 1298 void MarkCompactCollector::MarkMapContents(Map* map) { |
1299 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>( | 1299 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>( |
1300 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); | 1300 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); |
1301 | 1301 |
1302 // Mark the Object* fields of the Map. | 1302 // Mark the Object* fields of the Map. |
1303 // Since the descriptor array has been marked already, it is fine | 1303 // Since the descriptor array has been marked already, it is fine |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 // If the pair (value, details) at index i, i+1 is not | 1338 // If the pair (value, details) at index i, i+1 is not |
1339 // a transition or null descriptor, mark the value. | 1339 // a transition or null descriptor, mark the value. |
1340 PropertyDetails details(Smi::cast(contents->get(i + 1))); | 1340 PropertyDetails details(Smi::cast(contents->get(i + 1))); |
1341 if (details.type() < FIRST_PHANTOM_PROPERTY_TYPE) { | 1341 if (details.type() < FIRST_PHANTOM_PROPERTY_TYPE) { |
1342 HeapObject* object = reinterpret_cast<HeapObject*>(contents->get(i)); | 1342 HeapObject* object = reinterpret_cast<HeapObject*>(contents->get(i)); |
1343 if (object->IsHeapObject()) { | 1343 if (object->IsHeapObject()) { |
1344 // TODO(gc) ISOLATES MERGE | 1344 // TODO(gc) ISOLATES MERGE |
1345 MarkBit mark = HEAP->marking()->MarkBitFrom(HeapObject::cast(object)); | 1345 MarkBit mark = HEAP->marking()->MarkBitFrom(HeapObject::cast(object)); |
1346 if (!mark.Get()) { | 1346 if (!mark.Get()) { |
1347 SetMark(HeapObject::cast(object), mark); | 1347 SetMark(HeapObject::cast(object), mark); |
1348 marking_stack_.Push(object); | 1348 marking_deque_.Push(object); |
1349 } | 1349 } |
1350 } | 1350 } |
1351 } | 1351 } |
1352 } | 1352 } |
1353 // The DescriptorArray descriptors contains a pointer to its contents array, | 1353 // The DescriptorArray descriptors contains a pointer to its contents array, |
1354 // but the contents array is already marked. | 1354 // but the contents array is already marked. |
1355 marking_stack_.Push(descriptors); | 1355 marking_deque_.Push(descriptors); |
1356 } | 1356 } |
1357 | 1357 |
1358 | 1358 |
1359 void MarkCompactCollector::CreateBackPointers() { | 1359 void MarkCompactCollector::CreateBackPointers() { |
1360 HeapObjectIterator iterator(HEAP->map_space()); | 1360 HeapObjectIterator iterator(HEAP->map_space()); |
1361 for (HeapObject* next_object = iterator.Next(); | 1361 for (HeapObject* next_object = iterator.Next(); |
1362 next_object != NULL; next_object = iterator.Next()) { | 1362 next_object != NULL; next_object = iterator.Next()) { |
1363 if (next_object->IsMap()) { // Could also be FreeSpace object on free list. | 1363 if (next_object->IsMap()) { // Could also be FreeSpace object on free list. |
1364 Map* map = Map::cast(next_object); | 1364 Map* map = Map::cast(next_object); |
1365 if (map->instance_type() >= FIRST_JS_OBJECT_TYPE && | 1365 if (map->instance_type() >= FIRST_JS_OBJECT_TYPE && |
(...skipping 17 matching lines...) Expand all Loading... |
1383 | 1383 |
1384 | 1384 |
1385 // Fill the marking stack with overflowed objects returned by the given | 1385 // Fill the marking stack with overflowed objects returned by the given |
1386 // iterator. Stop when the marking stack is filled or the end of the space | 1386 // iterator. Stop when the marking stack is filled or the end of the space |
1387 // is reached, whichever comes first. | 1387 // is reached, whichever comes first. |
1388 template<class T> | 1388 template<class T> |
1389 static void ScanOverflowedObjects(T* it) { | 1389 static void ScanOverflowedObjects(T* it) { |
1390 #if 0 | 1390 #if 0 |
1391 // The caller should ensure that the marking stack is initially not full, | 1391 // The caller should ensure that the marking stack is initially not full, |
1392 // so that we don't waste effort pointlessly scanning for objects. | 1392 // so that we don't waste effort pointlessly scanning for objects. |
1393 ASSERT(!marking_stack.is_full()); | 1393 ASSERT(!marking_deque.is_full()); |
1394 | 1394 |
1395 for (HeapObject* object = it->next(); object != NULL; object = it->next()) { | 1395 for (HeapObject* object = it->next(); object != NULL; object = it->next()) { |
1396 if (object->IsOverflowed()) { | 1396 if (object->IsOverflowed()) { |
1397 object->ClearOverflow(); | 1397 object->ClearOverflow(); |
1398 ASSERT(HEAP->mark_compact_collector()->IsMarked(object)); | 1398 ASSERT(HEAP->mark_compact_collector()->IsMarked(object)); |
1399 ASSERT(HEAP->Contains(object)); | 1399 ASSERT(HEAP->Contains(object)); |
1400 marking_stack.Push(object); | 1400 marking_deque.Push(object); |
1401 if (marking_stack.is_full()) return; | 1401 if (marking_deque.is_full()) return; |
1402 } | 1402 } |
1403 } | 1403 } |
1404 #endif | 1404 #endif |
1405 UNREACHABLE(); | 1405 UNREACHABLE(); |
1406 } | 1406 } |
1407 | 1407 |
1408 | 1408 |
1409 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { | 1409 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { |
1410 Object* o = *p; | 1410 Object* o = *p; |
1411 if (!o->IsHeapObject()) return false; | 1411 if (!o->IsHeapObject()) return false; |
1412 HeapObject* heap_object = HeapObject::cast(o); | 1412 HeapObject* heap_object = HeapObject::cast(o); |
1413 // TODO(gc) ISOLATES MERGE | 1413 // TODO(gc) ISOLATES MERGE |
1414 MarkBit mark = HEAP->marking()->MarkBitFrom(heap_object); | 1414 MarkBit mark = HEAP->marking()->MarkBitFrom(heap_object); |
1415 return !mark.Get(); | 1415 return !mark.Get(); |
1416 } | 1416 } |
1417 | 1417 |
1418 | 1418 |
1419 void MarkCompactCollector::MarkSymbolTable() { | 1419 void MarkCompactCollector::MarkSymbolTable() { |
1420 SymbolTable* symbol_table = heap_->raw_unchecked_symbol_table(); | 1420 SymbolTable* symbol_table = heap_->raw_unchecked_symbol_table(); |
1421 // Mark the symbol table itself. | 1421 // Mark the symbol table itself. |
1422 MarkBit symbol_table_mark = heap_->marking()->MarkBitFrom(symbol_table); | 1422 MarkBit symbol_table_mark = heap_->marking()->MarkBitFrom(symbol_table); |
1423 SetMark(symbol_table, symbol_table_mark); | 1423 SetMark(symbol_table, symbol_table_mark); |
1424 // Explicitly mark the prefix. | 1424 // Explicitly mark the prefix. |
1425 MarkingVisitor marker(heap_); | 1425 MarkingVisitor marker(heap_); |
1426 symbol_table->IteratePrefix(&marker); | 1426 symbol_table->IteratePrefix(&marker); |
1427 ProcessMarkingStack(); | 1427 ProcessMarkingDeque(); |
1428 } | 1428 } |
1429 | 1429 |
1430 | 1430 |
1431 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { | 1431 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { |
1432 // Mark the heap roots including global variables, stack variables, | 1432 // Mark the heap roots including global variables, stack variables, |
1433 // etc., and all objects reachable from them. | 1433 // etc., and all objects reachable from them. |
1434 HEAP->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); | 1434 HEAP->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); |
1435 | 1435 |
1436 // Handle the symbol table specially. | 1436 // Handle the symbol table specially. |
1437 MarkSymbolTable(); | 1437 MarkSymbolTable(); |
1438 | 1438 |
1439 // There may be overflowed objects in the heap. Visit them now. | 1439 // There may be overflowed objects in the heap. Visit them now. |
1440 while (marking_stack_.overflowed()) { | 1440 while (marking_deque_.overflowed()) { |
1441 RefillMarkingStack(); | 1441 RefillMarkingDeque(); |
1442 EmptyMarkingStack(); | 1442 EmptyMarkingDeque(); |
1443 } | 1443 } |
1444 } | 1444 } |
1445 | 1445 |
1446 | 1446 |
1447 void MarkCompactCollector::MarkObjectGroups() { | 1447 void MarkCompactCollector::MarkObjectGroups() { |
1448 List<ObjectGroup*>* object_groups = | 1448 List<ObjectGroup*>* object_groups = |
1449 heap_->isolate()->global_handles()->object_groups(); | 1449 heap_->isolate()->global_handles()->object_groups(); |
1450 | 1450 |
1451 for (int i = 0; i < object_groups->length(); i++) { | 1451 for (int i = 0; i < object_groups->length(); i++) { |
1452 ObjectGroup* entry = object_groups->at(i); | 1452 ObjectGroup* entry = object_groups->at(i); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 delete entry; | 1513 delete entry; |
1514 ref_groups->at(i) = NULL; | 1514 ref_groups->at(i) = NULL; |
1515 } | 1515 } |
1516 } | 1516 } |
1517 | 1517 |
1518 | 1518 |
1519 // Mark all objects reachable from the objects on the marking stack. | 1519 // Mark all objects reachable from the objects on the marking stack. |
1520 // Before: the marking stack contains zero or more heap object pointers. | 1520 // Before: the marking stack contains zero or more heap object pointers. |
1521 // After: the marking stack is empty, and all objects reachable from the | 1521 // After: the marking stack is empty, and all objects reachable from the |
1522 // marking stack have been marked, or are overflowed in the heap. | 1522 // marking stack have been marked, or are overflowed in the heap. |
1523 void MarkCompactCollector::EmptyMarkingStack() { | 1523 void MarkCompactCollector::EmptyMarkingDeque() { |
1524 while (!marking_stack_.is_empty()) { | 1524 while (!marking_deque_.IsEmpty()) { |
1525 HeapObject* object = marking_stack_.Pop(); | 1525 HeapObject* object = marking_deque_.Pop(); |
1526 ASSERT(object->IsHeapObject()); | 1526 ASSERT(object->IsHeapObject()); |
1527 ASSERT(heap_->Contains(object)); | 1527 ASSERT(heap_->Contains(object)); |
1528 ASSERT(IsMarked(object)); | 1528 ASSERT(IsMarked(object)); |
1529 ASSERT(!object->IsOverflowed()); | 1529 ASSERT(!object->IsOverflowed()); |
1530 | 1530 |
1531 Map* map = object->map(); | 1531 Map* map = object->map(); |
1532 MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 1532 MarkBit map_mark = Marking::MarkBitFromOldSpace(map); |
1533 MarkObject(map, map_mark); | 1533 MarkObject(map, map_mark); |
1534 | 1534 |
1535 StaticMarkingVisitor::IterateBody(map, object); | 1535 StaticMarkingVisitor::IterateBody(map, object); |
1536 } | 1536 } |
1537 } | 1537 } |
1538 | 1538 |
1539 | 1539 |
1540 // Sweep the heap for overflowed objects, clear their overflow bits, and | 1540 // Sweep the heap for overflowed objects, clear their overflow bits, and |
1541 // push them on the marking stack. Stop early if the marking stack fills | 1541 // push them on the marking stack. Stop early if the marking stack fills |
1542 // before sweeping completes. If sweeping completes, there are no remaining | 1542 // before sweeping completes. If sweeping completes, there are no remaining |
1543 // overflowed objects in the heap so the overflow flag on the markings stack | 1543 // overflowed objects in the heap so the overflow flag on the markings stack |
1544 // is cleared. | 1544 // is cleared. |
1545 void MarkCompactCollector::RefillMarkingStack() { | 1545 void MarkCompactCollector::RefillMarkingDeque() { |
1546 UNREACHABLE(); | 1546 UNREACHABLE(); |
1547 | 1547 |
1548 #if 0 | 1548 #if 0 |
1549 ASSERT(marking_stack_.overflowed()); | 1549 ASSERT(marking_deque_.overflowed()); |
1550 | 1550 |
1551 SemiSpaceIterator new_it(HEAP->new_space(), &OverflowObjectSize); | 1551 SemiSpaceIterator new_it(HEAP->new_space(), &OverflowObjectSize); |
1552 OverflowedObjectsScanner::ScanOverflowedObjects(this, &new_it); | 1552 OverflowedObjectsScanner::ScanOverflowedObjects(this, &new_it); |
1553 if (marking_stack_.is_full()) return; | 1553 if (marking_deque_.is_full()) return; |
1554 | 1554 |
1555 HeapObjectIterator old_pointer_it(HEAP->old_pointer_space(), | 1555 HeapObjectIterator old_pointer_it(HEAP->old_pointer_space(), |
1556 &OverflowObjectSize); | 1556 &OverflowObjectSize); |
1557 OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_pointer_it); | 1557 OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_pointer_it); |
1558 if (marking_stack_.is_full()) return; | 1558 if (marking_deque_.is_full()) return; |
1559 | 1559 |
1560 HeapObjectIterator old_data_it(HEAP->old_data_space(), &OverflowObjectSize); | 1560 HeapObjectIterator old_data_it(HEAP->old_data_space(), &OverflowObjectSize); |
1561 OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_data_it); | 1561 OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_data_it); |
1562 if (marking_stack_.is_full()) return; | 1562 if (marking_deque_.is_full()) return; |
1563 | 1563 |
1564 HeapObjectIterator code_it(HEAP->code_space(), &OverflowObjectSize); | 1564 HeapObjectIterator code_it(HEAP->code_space(), &OverflowObjectSize); |
1565 OverflowedObjectsScanner::ScanOverflowedObjects(this, &code_it); | 1565 OverflowedObjectsScanner::ScanOverflowedObjects(this, &code_it); |
1566 if (marking_stack_.is_full()) return; | 1566 if (marking_deque_.is_full()) return; |
1567 | 1567 |
1568 HeapObjectIterator map_it(HEAP->map_space(), &OverflowObjectSize); | 1568 HeapObjectIterator map_it(HEAP->map_space(), &OverflowObjectSize); |
1569 OverflowedObjectsScanner::ScanOverflowedObjects(this, &map_it); | 1569 OverflowedObjectsScanner::ScanOverflowedObjects(this, &map_it); |
1570 if (marking_stack_.is_full()) return; | 1570 if (marking_deque_.is_full()) return; |
1571 | 1571 |
1572 HeapObjectIterator cell_it(HEAP->cell_space(), &OverflowObjectSize); | 1572 HeapObjectIterator cell_it(HEAP->cell_space(), &OverflowObjectSize); |
1573 OverflowedObjectsScanner::ScanOverflowedObjects(this, &cell_it); | 1573 OverflowedObjectsScanner::ScanOverflowedObjects(this, &cell_it); |
1574 if (marking_stack_.is_full()) return; | 1574 if (marking_deque_.is_full()) return; |
1575 | 1575 |
1576 LargeObjectIterator lo_it(HEAP->lo_space(), &OverflowObjectSize); | 1576 LargeObjectIterator lo_it(HEAP->lo_space(), &OverflowObjectSize); |
1577 OverflowedObjectsScanner::ScanOverflowedObjects(this, &lo_it); | 1577 OverflowedObjectsScanner::ScanOverflowedObjects(this, &lo_it); |
1578 if (marking_stack_.is_full()) return; | 1578 if (marking_deque_.is_full()) return; |
1579 | 1579 |
1580 marking_stack_.clear_overflowed(); | 1580 marking_deque_.clear_overflowed(); |
1581 #endif | 1581 #endif |
1582 } | 1582 } |
1583 | 1583 |
1584 | 1584 |
1585 // Mark all objects reachable (transitively) from objects on the marking | 1585 // Mark all objects reachable (transitively) from objects on the marking |
1586 // stack. Before: the marking stack contains zero or more heap object | 1586 // stack. Before: the marking stack contains zero or more heap object |
1587 // pointers. After: the marking stack is empty and there are no overflowed | 1587 // pointers. After: the marking stack is empty and there are no overflowed |
1588 // objects in the heap. | 1588 // objects in the heap. |
1589 void MarkCompactCollector::ProcessMarkingStack() { | 1589 void MarkCompactCollector::ProcessMarkingDeque() { |
1590 EmptyMarkingStack(); | 1590 EmptyMarkingDeque(); |
1591 while (marking_stack_.overflowed()) { | 1591 while (marking_deque_.overflowed()) { |
1592 RefillMarkingStack(); | 1592 RefillMarkingDeque(); |
1593 EmptyMarkingStack(); | 1593 EmptyMarkingDeque(); |
1594 } | 1594 } |
1595 } | 1595 } |
1596 | 1596 |
1597 | 1597 |
1598 void MarkCompactCollector::ProcessExternalMarking() { | 1598 void MarkCompactCollector::ProcessExternalMarking() { |
1599 bool work_to_do = true; | 1599 bool work_to_do = true; |
1600 ASSERT(marking_stack_.is_empty()); | 1600 ASSERT(marking_deque_.IsEmpty()); |
1601 while (work_to_do) { | 1601 while (work_to_do) { |
1602 MarkObjectGroups(); | 1602 MarkObjectGroups(); |
1603 MarkImplicitRefGroups(); | 1603 MarkImplicitRefGroups(); |
1604 work_to_do = !marking_stack_.is_empty(); | 1604 work_to_do = !marking_deque_.IsEmpty(); |
1605 ProcessMarkingStack(); | 1605 ProcessMarkingDeque(); |
1606 } | 1606 } |
1607 } | 1607 } |
1608 | 1608 |
1609 | 1609 |
1610 void MarkCompactCollector::MarkLiveObjects() { | 1610 void MarkCompactCollector::MarkLiveObjects() { |
1611 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); | 1611 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); |
1612 // The recursive GC marker detects when it is nearing stack overflow, | 1612 // The recursive GC marker detects when it is nearing stack overflow, |
1613 // and switches to a different marking system. JS interrupts interfere | 1613 // and switches to a different marking system. JS interrupts interfere |
1614 // with the C stack limit check. | 1614 // with the C stack limit check. |
1615 PostponeInterruptsScope postpone(heap_->isolate()); | 1615 PostponeInterruptsScope postpone(heap_->isolate()); |
1616 | 1616 |
1617 #ifdef DEBUG | 1617 #ifdef DEBUG |
1618 ASSERT(state_ == PREPARE_GC); | 1618 ASSERT(state_ == PREPARE_GC); |
1619 state_ = MARK_LIVE_OBJECTS; | 1619 state_ = MARK_LIVE_OBJECTS; |
1620 #endif | 1620 #endif |
1621 // The to space contains live objects, the from space is used as a marking | 1621 // The to space contains live objects, the from space is used as a marking |
1622 // stack. | 1622 // stack. |
1623 marking_stack_.Initialize(heap_->new_space()->FromSpaceLow(), | 1623 marking_deque_.Initialize(heap_->new_space()->FromSpaceLow(), |
1624 heap_->new_space()->FromSpaceHigh()); | 1624 heap_->new_space()->FromSpaceHigh()); |
1625 | 1625 |
1626 ASSERT(!marking_stack_.overflowed()); | 1626 ASSERT(!marking_deque_.overflowed()); |
1627 | 1627 |
1628 PrepareForCodeFlushing(); | 1628 PrepareForCodeFlushing(); |
1629 | 1629 |
1630 RootMarkingVisitor root_visitor(heap_); | 1630 RootMarkingVisitor root_visitor(heap_); |
1631 MarkRoots(&root_visitor); | 1631 MarkRoots(&root_visitor); |
1632 | 1632 |
1633 // The objects reachable from the roots are marked, yet unreachable | 1633 // The objects reachable from the roots are marked, yet unreachable |
1634 // objects are unmarked. Mark objects reachable due to host | 1634 // objects are unmarked. Mark objects reachable due to host |
1635 // application specific logic. | 1635 // application specific logic. |
1636 ProcessExternalMarking(); | 1636 ProcessExternalMarking(); |
1637 | 1637 |
1638 // The objects reachable from the roots or object groups are marked, | 1638 // The objects reachable from the roots or object groups are marked, |
1639 // yet unreachable objects are unmarked. Mark objects reachable | 1639 // yet unreachable objects are unmarked. Mark objects reachable |
1640 // only from weak global handles. | 1640 // only from weak global handles. |
1641 // | 1641 // |
1642 // First we identify nonlive weak handles and mark them as pending | 1642 // First we identify nonlive weak handles and mark them as pending |
1643 // destruction. | 1643 // destruction. |
1644 heap_->isolate()->global_handles()->IdentifyWeakHandles( | 1644 heap_->isolate()->global_handles()->IdentifyWeakHandles( |
1645 &IsUnmarkedHeapObject); | 1645 &IsUnmarkedHeapObject); |
1646 // Then we mark the objects and process the transitive closure. | 1646 // Then we mark the objects and process the transitive closure. |
1647 heap_->isolate()->global_handles()->IterateWeakRoots(&root_visitor); | 1647 heap_->isolate()->global_handles()->IterateWeakRoots(&root_visitor); |
1648 while (marking_stack_.overflowed()) { | 1648 while (marking_deque_.overflowed()) { |
1649 RefillMarkingStack(); | 1649 RefillMarkingDeque(); |
1650 EmptyMarkingStack(); | 1650 EmptyMarkingDeque(); |
1651 } | 1651 } |
1652 | 1652 |
1653 // Repeat host application specific marking to mark unmarked objects | 1653 // Repeat host application specific marking to mark unmarked objects |
1654 // reachable from the weak roots. | 1654 // reachable from the weak roots. |
1655 ProcessExternalMarking(); | 1655 ProcessExternalMarking(); |
1656 | 1656 |
1657 AfterMarking(); | 1657 AfterMarking(); |
1658 } | 1658 } |
1659 | 1659 |
1660 | 1660 |
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2655 } | 2655 } |
2656 | 2656 |
2657 | 2657 |
2658 void MarkCompactCollector::Initialize() { | 2658 void MarkCompactCollector::Initialize() { |
2659 StaticPointersToNewGenUpdatingVisitor::Initialize(); | 2659 StaticPointersToNewGenUpdatingVisitor::Initialize(); |
2660 StaticMarkingVisitor::Initialize(); | 2660 StaticMarkingVisitor::Initialize(); |
2661 } | 2661 } |
2662 | 2662 |
2663 | 2663 |
2664 } } // namespace v8::internal | 2664 } } // namespace v8::internal |
OLD | NEW |