| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 1191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 // There may be overflowed objects in the heap. Visit them now. | 1202 // There may be overflowed objects in the heap. Visit them now. |
| 1203 while (marking_stack_.overflowed()) { | 1203 while (marking_stack_.overflowed()) { |
| 1204 RefillMarkingStack(); | 1204 RefillMarkingStack(); |
| 1205 EmptyMarkingStack(); | 1205 EmptyMarkingStack(); |
| 1206 } | 1206 } |
| 1207 } | 1207 } |
| 1208 | 1208 |
| 1209 | 1209 |
| 1210 void MarkCompactCollector::MarkObjectGroups() { | 1210 void MarkCompactCollector::MarkObjectGroups() { |
| 1211 List<ObjectGroup*>* object_groups = | 1211 List<ObjectGroup*>* object_groups = |
| 1212 heap_->isolate_->global_handles()->object_groups(); | 1212 heap_->isolate()->global_handles()->object_groups(); |
| 1213 | 1213 |
| 1214 for (int i = 0; i < object_groups->length(); i++) { | 1214 for (int i = 0; i < object_groups->length(); i++) { |
| 1215 ObjectGroup* entry = object_groups->at(i); | 1215 ObjectGroup* entry = object_groups->at(i); |
| 1216 if (entry == NULL) continue; | 1216 if (entry == NULL) continue; |
| 1217 | 1217 |
| 1218 List<Object**>& objects = entry->objects_; | 1218 List<Object**>& objects = entry->objects_; |
| 1219 bool group_marked = false; | 1219 bool group_marked = false; |
| 1220 for (int j = 0; j < objects.length(); j++) { | 1220 for (int j = 0; j < objects.length(); j++) { |
| 1221 Object* object = *objects[j]; | 1221 Object* object = *objects[j]; |
| 1222 if (object->IsHeapObject() && HeapObject::cast(object)->IsMarked()) { | 1222 if (object->IsHeapObject() && HeapObject::cast(object)->IsMarked()) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1359 // containing at least one marked object, and continue until no new | 1359 // containing at least one marked object, and continue until no new |
| 1360 // objects are reachable from the object groups. | 1360 // objects are reachable from the object groups. |
| 1361 ProcessObjectGroups(); | 1361 ProcessObjectGroups(); |
| 1362 | 1362 |
| 1363 // The objects reachable from the roots or object groups are marked, | 1363 // The objects reachable from the roots or object groups are marked, |
| 1364 // yet unreachable objects are unmarked. Mark objects reachable | 1364 // yet unreachable objects are unmarked. Mark objects reachable |
| 1365 // only from weak global handles. | 1365 // only from weak global handles. |
| 1366 // | 1366 // |
| 1367 // First we identify nonlive weak handles and mark them as pending | 1367 // First we identify nonlive weak handles and mark them as pending |
| 1368 // destruction. | 1368 // destruction. |
| 1369 heap_->isolate_->global_handles()->IdentifyWeakHandles(&IsUnmarkedHeapObject); | 1369 heap_->isolate()->global_handles()->IdentifyWeakHandles( |
| 1370 &IsUnmarkedHeapObject); |
| 1370 // Then we mark the objects and process the transitive closure. | 1371 // Then we mark the objects and process the transitive closure. |
| 1371 heap_->isolate_->global_handles()->IterateWeakRoots(&root_visitor); | 1372 heap_->isolate()->global_handles()->IterateWeakRoots(&root_visitor); |
| 1372 while (marking_stack_.overflowed()) { | 1373 while (marking_stack_.overflowed()) { |
| 1373 RefillMarkingStack(); | 1374 RefillMarkingStack(); |
| 1374 EmptyMarkingStack(); | 1375 EmptyMarkingStack(); |
| 1375 } | 1376 } |
| 1376 | 1377 |
| 1377 // Repeat the object groups to mark unmarked groups reachable from the | 1378 // Repeat the object groups to mark unmarked groups reachable from the |
| 1378 // weak roots. | 1379 // weak roots. |
| 1379 ProcessObjectGroups(); | 1380 ProcessObjectGroups(); |
| 1380 | 1381 |
| 1381 // Prune the symbol table removing all symbols only pointed to by the | 1382 // Prune the symbol table removing all symbols only pointed to by the |
| 1382 // symbol table. Cannot use symbol_table() here because the symbol | 1383 // symbol table. Cannot use symbol_table() here because the symbol |
| 1383 // table is marked. | 1384 // table is marked. |
| 1384 SymbolTable* symbol_table = heap_->raw_unchecked_symbol_table(); | 1385 SymbolTable* symbol_table = heap_->raw_unchecked_symbol_table(); |
| 1385 SymbolTableCleaner v; | 1386 SymbolTableCleaner v; |
| 1386 symbol_table->IterateElements(&v); | 1387 symbol_table->IterateElements(&v); |
| 1387 symbol_table->ElementsRemoved(v.PointersRemoved()); | 1388 symbol_table->ElementsRemoved(v.PointersRemoved()); |
| 1388 heap_->external_string_table_.Iterate(&v); | 1389 heap_->external_string_table_.Iterate(&v); |
| 1389 heap_->external_string_table_.CleanUp(); | 1390 heap_->external_string_table_.CleanUp(); |
| 1390 | 1391 |
| 1391 // Process the weak references. | 1392 // Process the weak references. |
| 1392 MarkCompactWeakObjectRetainer mark_compact_object_retainer; | 1393 MarkCompactWeakObjectRetainer mark_compact_object_retainer; |
| 1393 heap_->ProcessWeakReferences(&mark_compact_object_retainer); | 1394 heap_->ProcessWeakReferences(&mark_compact_object_retainer); |
| 1394 | 1395 |
| 1395 // Remove object groups after marking phase. | 1396 // Remove object groups after marking phase. |
| 1396 heap_->isolate_->global_handles()->RemoveObjectGroups(); | 1397 heap_->isolate()->global_handles()->RemoveObjectGroups(); |
| 1397 | 1398 |
| 1398 // Flush code from collected candidates. | 1399 // Flush code from collected candidates. |
| 1399 if (is_code_flushing_enabled()) { | 1400 if (is_code_flushing_enabled()) { |
| 1400 code_flusher_->ProcessCandidates(); | 1401 code_flusher_->ProcessCandidates(); |
| 1401 } | 1402 } |
| 1403 |
| 1404 // Clean up dead objects from the runtime profiler. |
| 1405 heap_->isolate()->runtime_profiler()->RemoveDeadSamples(); |
| 1402 } | 1406 } |
| 1403 | 1407 |
| 1404 | 1408 |
| 1405 #ifdef DEBUG | 1409 #ifdef DEBUG |
| 1406 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) { | 1410 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) { |
| 1407 live_bytes_ += obj->Size(); | 1411 live_bytes_ += obj->Size(); |
| 1408 if (HEAP->new_space()->Contains(obj)) { | 1412 if (HEAP->new_space()->Contains(obj)) { |
| 1409 live_young_objects_size_ += obj->Size(); | 1413 live_young_objects_size_ += obj->Size(); |
| 1410 } else if (HEAP->map_space()->Contains(obj)) { | 1414 } else if (HEAP->map_space()->Contains(obj)) { |
| 1411 ASSERT(obj->IsMap()); | 1415 ASSERT(obj->IsMap()); |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1995 // Update pointer from the global contexts list. | 1999 // Update pointer from the global contexts list. |
| 1996 updating_visitor.VisitPointer(heap->global_contexts_list_address()); | 2000 updating_visitor.VisitPointer(heap->global_contexts_list_address()); |
| 1997 | 2001 |
| 1998 // Update pointers from external string table. | 2002 // Update pointers from external string table. |
| 1999 heap->UpdateNewSpaceReferencesInExternalStringTable( | 2003 heap->UpdateNewSpaceReferencesInExternalStringTable( |
| 2000 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 2004 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 2001 | 2005 |
| 2002 // All pointers were updated. Update auxiliary allocation info. | 2006 // All pointers were updated. Update auxiliary allocation info. |
| 2003 heap->IncrementYoungSurvivorsCounter(survivors_size); | 2007 heap->IncrementYoungSurvivorsCounter(survivors_size); |
| 2004 space->set_age_mark(space->top()); | 2008 space->set_age_mark(space->top()); |
| 2009 |
| 2010 // Update JSFunction pointers from the runtime profiler. |
| 2011 heap->isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); |
| 2005 } | 2012 } |
| 2006 | 2013 |
| 2007 | 2014 |
| 2008 static void SweepSpace(Heap* heap, PagedSpace* space) { | 2015 static void SweepSpace(Heap* heap, PagedSpace* space) { |
| 2009 PageIterator it(space, PageIterator::PAGES_IN_USE); | 2016 PageIterator it(space, PageIterator::PAGES_IN_USE); |
| 2010 | 2017 |
| 2011 // During sweeping of paged space we are trying to find longest sequences | 2018 // During sweeping of paged space we are trying to find longest sequences |
| 2012 // of pages without live objects and free them (instead of putting them on | 2019 // of pages without live objects and free them (instead of putting them on |
| 2013 // the free list). | 2020 // the free list). |
| 2014 | 2021 |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2230 } | 2237 } |
| 2231 | 2238 |
| 2232 #ifdef DEBUG | 2239 #ifdef DEBUG |
| 2233 CheckNoMapsToEvacuate(); | 2240 CheckNoMapsToEvacuate(); |
| 2234 #endif | 2241 #endif |
| 2235 } | 2242 } |
| 2236 | 2243 |
| 2237 void UpdateMapPointersInRoots() { | 2244 void UpdateMapPointersInRoots() { |
| 2238 MapUpdatingVisitor map_updating_visitor; | 2245 MapUpdatingVisitor map_updating_visitor; |
| 2239 heap_->IterateRoots(&map_updating_visitor, VISIT_ONLY_STRONG); | 2246 heap_->IterateRoots(&map_updating_visitor, VISIT_ONLY_STRONG); |
| 2240 heap_->isolate_->global_handles()->IterateWeakRoots(&map_updating_visitor); | 2247 heap_->isolate()->global_handles()->IterateWeakRoots(&map_updating_visitor); |
| 2241 LiveObjectList::IterateElements(&map_updating_visitor); | 2248 LiveObjectList::IterateElements(&map_updating_visitor); |
| 2242 } | 2249 } |
| 2243 | 2250 |
| 2244 void UpdateMapPointersInPagedSpace(PagedSpace* space) { | 2251 void UpdateMapPointersInPagedSpace(PagedSpace* space) { |
| 2245 ASSERT(space != heap_->map_space()); | 2252 ASSERT(space != heap_->map_space()); |
| 2246 | 2253 |
| 2247 PageIterator it(space, PageIterator::PAGES_IN_USE); | 2254 PageIterator it(space, PageIterator::PAGES_IN_USE); |
| 2248 while (it.has_next()) { | 2255 while (it.has_next()) { |
| 2249 Page* p = it.next(); | 2256 Page* p = it.next(); |
| 2250 UpdateMapPointersInRange(heap_, p->ObjectAreaStart(), p->AllocationTop()); | 2257 UpdateMapPointersInRange(heap_, p->ObjectAreaStart(), p->AllocationTop()); |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2598 Heap* heap_; | 2605 Heap* heap_; |
| 2599 }; | 2606 }; |
| 2600 | 2607 |
| 2601 | 2608 |
| 2602 void MarkCompactCollector::UpdatePointers() { | 2609 void MarkCompactCollector::UpdatePointers() { |
| 2603 #ifdef DEBUG | 2610 #ifdef DEBUG |
| 2604 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); | 2611 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); |
| 2605 state_ = UPDATE_POINTERS; | 2612 state_ = UPDATE_POINTERS; |
| 2606 #endif | 2613 #endif |
| 2607 UpdatingVisitor updating_visitor(heap_); | 2614 UpdatingVisitor updating_visitor(heap_); |
| 2615 heap_->isolate()->runtime_profiler()->UpdateSamplesAfterCompact( |
| 2616 &updating_visitor); |
| 2608 heap_->IterateRoots(&updating_visitor, VISIT_ONLY_STRONG); | 2617 heap_->IterateRoots(&updating_visitor, VISIT_ONLY_STRONG); |
| 2609 heap_->isolate_->global_handles()->IterateWeakRoots(&updating_visitor); | 2618 heap_->isolate()->global_handles()->IterateWeakRoots(&updating_visitor); |
| 2610 | 2619 |
| 2611 // Update the pointer to the head of the weak list of global contexts. | 2620 // Update the pointer to the head of the weak list of global contexts. |
| 2612 updating_visitor.VisitPointer(&heap_->global_contexts_list_); | 2621 updating_visitor.VisitPointer(&heap_->global_contexts_list_); |
| 2613 | 2622 |
| 2614 LiveObjectList::IterateElements(&updating_visitor); | 2623 LiveObjectList::IterateElements(&updating_visitor); |
| 2615 | 2624 |
| 2616 int live_maps_size = IterateLiveObjects( | 2625 int live_maps_size = IterateLiveObjects( |
| 2617 heap_->map_space(), &MarkCompactCollector::UpdatePointersInOldObject); | 2626 heap_->map_space(), &MarkCompactCollector::UpdatePointersInOldObject); |
| 2618 int live_pointer_olds_size = IterateLiveObjects( | 2627 int live_pointer_olds_size = IterateLiveObjects( |
| 2619 heap_->old_pointer_space(), | 2628 heap_->old_pointer_space(), |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2885 } else { | 2894 } else { |
| 2886 heap_->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr, | 2895 heap_->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr, |
| 2887 old_addr, | 2896 old_addr, |
| 2888 obj_size); | 2897 obj_size); |
| 2889 } | 2898 } |
| 2890 } | 2899 } |
| 2891 | 2900 |
| 2892 ASSERT(!HeapObject::FromAddress(new_addr)->IsCode()); | 2901 ASSERT(!HeapObject::FromAddress(new_addr)->IsCode()); |
| 2893 | 2902 |
| 2894 HeapObject* copied_to = HeapObject::FromAddress(new_addr); | 2903 HeapObject* copied_to = HeapObject::FromAddress(new_addr); |
| 2895 if (copied_to->IsJSFunction()) { | 2904 if (copied_to->IsSharedFunctionInfo()) { |
| 2896 PROFILE(FunctionMoveEvent(heap_, old_addr, new_addr)); | 2905 PROFILE(SFIMoveEvent(old_addr, new_addr)); |
| 2897 PROFILE(FunctionCreateEventFromMove(heap_, JSFunction::cast(copied_to))); | |
| 2898 } | 2906 } |
| 2899 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); | 2907 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); |
| 2900 | 2908 |
| 2901 return obj_size; | 2909 return obj_size; |
| 2902 } | 2910 } |
| 2903 | 2911 |
| 2904 | 2912 |
| 2905 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) { | 2913 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) { |
| 2906 return RelocateOldNonCodeObject(obj, heap_->old_pointer_space()); | 2914 return RelocateOldNonCodeObject(obj, heap_->old_pointer_space()); |
| 2907 } | 2915 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2978 obj_size); | 2986 obj_size); |
| 2979 } | 2987 } |
| 2980 | 2988 |
| 2981 #ifdef DEBUG | 2989 #ifdef DEBUG |
| 2982 if (FLAG_gc_verbose) { | 2990 if (FLAG_gc_verbose) { |
| 2983 PrintF("relocate %p -> %p\n", old_addr, new_addr); | 2991 PrintF("relocate %p -> %p\n", old_addr, new_addr); |
| 2984 } | 2992 } |
| 2985 #endif | 2993 #endif |
| 2986 | 2994 |
| 2987 HeapObject* copied_to = HeapObject::FromAddress(new_addr); | 2995 HeapObject* copied_to = HeapObject::FromAddress(new_addr); |
| 2988 if (copied_to->IsJSFunction()) { | 2996 if (copied_to->IsSharedFunctionInfo()) { |
| 2989 PROFILE(FunctionMoveEvent(heap_, old_addr, new_addr)); | 2997 PROFILE(SFIMoveEvent(old_addr, new_addr)); |
| 2990 PROFILE(FunctionCreateEventFromMove(heap_, JSFunction::cast(copied_to))); | |
| 2991 } | 2998 } |
| 2992 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); | 2999 HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr)); |
| 2993 | 3000 |
| 2994 return obj_size; | 3001 return obj_size; |
| 2995 } | 3002 } |
| 2996 | 3003 |
| 2997 | 3004 |
| 2998 void MarkCompactCollector::EnableCodeFlushing(bool enable) { | 3005 void MarkCompactCollector::EnableCodeFlushing(bool enable) { |
| 2999 if (enable) { | 3006 if (enable) { |
| 3000 if (code_flusher_ != NULL) return; | 3007 if (code_flusher_ != NULL) return; |
| 3001 code_flusher_ = new CodeFlusher(heap_->isolate()); | 3008 code_flusher_ = new CodeFlusher(heap_->isolate()); |
| 3002 } else { | 3009 } else { |
| 3003 if (code_flusher_ == NULL) return; | 3010 if (code_flusher_ == NULL) return; |
| 3004 delete code_flusher_; | 3011 delete code_flusher_; |
| 3005 code_flusher_ = NULL; | 3012 code_flusher_ = NULL; |
| 3006 } | 3013 } |
| 3007 } | 3014 } |
| 3008 | 3015 |
| 3009 | 3016 |
| 3010 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) { | 3017 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) { |
| 3011 #ifdef ENABLE_GDB_JIT_INTERFACE | 3018 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 3012 if (obj->IsCode()) { | 3019 if (obj->IsCode()) { |
| 3013 GDBJITInterface::RemoveCode(reinterpret_cast<Code*>(obj)); | 3020 GDBJITInterface::RemoveCode(reinterpret_cast<Code*>(obj)); |
| 3014 } | 3021 } |
| 3015 #endif | 3022 #endif |
| 3016 #ifdef ENABLE_LOGGING_AND_PROFILING | 3023 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 3017 if (obj->IsCode()) { | 3024 if (obj->IsCode()) { |
| 3018 PROFILE(CodeDeleteEvent(obj->address())); | 3025 PROFILE(CodeDeleteEvent(obj->address())); |
| 3019 } else if (obj->IsJSFunction()) { | |
| 3020 PROFILE(FunctionDeleteEvent(obj->address())); | |
| 3021 } | 3026 } |
| 3022 #endif | 3027 #endif |
| 3023 } | 3028 } |
| 3024 | 3029 |
| 3025 | 3030 |
| 3026 int MarkCompactCollector::SizeOfMarkedObject(HeapObject* obj) { | 3031 int MarkCompactCollector::SizeOfMarkedObject(HeapObject* obj) { |
| 3027 MapWord map_word = obj->map_word(); | 3032 MapWord map_word = obj->map_word(); |
| 3028 map_word.ClearMark(); | 3033 map_word.ClearMark(); |
| 3029 return obj->SizeFromMap(map_word.ToMap()); | 3034 return obj->SizeFromMap(map_word.ToMap()); |
| 3030 } | 3035 } |
| 3031 | 3036 |
| 3032 | 3037 |
| 3033 void MarkCompactCollector::Initialize() { | 3038 void MarkCompactCollector::Initialize() { |
| 3034 StaticPointersToNewGenUpdatingVisitor::Initialize(); | 3039 StaticPointersToNewGenUpdatingVisitor::Initialize(); |
| 3035 StaticMarkingVisitor::Initialize(); | 3040 StaticMarkingVisitor::Initialize(); |
| 3036 } | 3041 } |
| 3037 | 3042 |
| 3038 | 3043 |
| 3039 } } // namespace v8::internal | 3044 } } // namespace v8::internal |
| OLD | NEW |