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/v8.h" | 5 #include "src/v8.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/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
294 | 294 |
295 | 295 |
296 void MarkCompactCollector::CollectGarbage() { | 296 void MarkCompactCollector::CollectGarbage() { |
297 // Make sure that Prepare() has been called. The individual steps below will | 297 // Make sure that Prepare() has been called. The individual steps below will |
298 // update the state as they proceed. | 298 // update the state as they proceed. |
299 DCHECK(state_ == PREPARE_GC); | 299 DCHECK(state_ == PREPARE_GC); |
300 | 300 |
301 MarkLiveObjects(); | 301 MarkLiveObjects(); |
302 DCHECK(heap_->incremental_marking()->IsStopped()); | 302 DCHECK(heap_->incremental_marking()->IsStopped()); |
303 | 303 |
304 // ClearNonLiveReferences can deoptimize code in dependent code arrays. | |
305 // Process weak cells before so that weak cells in dependent code | |
306 // arrays are cleared or contain only live code objects. | |
307 ProcessAndClearWeakCells(); | |
308 | |
304 if (FLAG_collect_maps) ClearNonLiveReferences(); | 309 if (FLAG_collect_maps) ClearNonLiveReferences(); |
305 | 310 |
306 ProcessAndClearWeakCells(); | |
307 | 311 |
Hannes Payer (out of office)
2015/02/12 12:19:47
remove one more newline
ulan
2015/02/12 12:55:51
Done.
| |
308 ClearWeakCollections(); | 312 ClearWeakCollections(); |
309 | 313 |
310 heap_->set_encountered_weak_cells(Smi::FromInt(0)); | 314 heap_->set_encountered_weak_cells(Smi::FromInt(0)); |
311 | 315 |
312 #ifdef VERIFY_HEAP | 316 #ifdef VERIFY_HEAP |
313 if (FLAG_verify_heap) { | 317 if (FLAG_verify_heap) { |
314 VerifyMarking(heap_); | 318 VerifyMarking(heap_); |
315 } | 319 } |
316 #endif | 320 #endif |
317 | 321 |
318 SweepSpaces(); | 322 SweepSpaces(); |
319 | 323 |
320 #ifdef VERIFY_HEAP | 324 #ifdef VERIFY_HEAP |
321 if (heap()->weak_embedded_objects_verification_enabled()) { | 325 VerifyWeakEmbeddedObjectsInCode(); |
322 VerifyWeakEmbeddedObjectsInCode(); | |
323 } | |
324 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) { | 326 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) { |
325 VerifyOmittedMapChecks(); | 327 VerifyOmittedMapChecks(); |
326 } | 328 } |
327 #endif | 329 #endif |
328 | 330 |
329 Finish(); | 331 Finish(); |
330 | 332 |
331 if (marking_parity_ == EVEN_MARKING_PARITY) { | 333 if (marking_parity_ == EVEN_MARKING_PARITY) { |
332 marking_parity_ = ODD_MARKING_PARITY; | 334 marking_parity_ = ODD_MARKING_PARITY; |
333 } else { | 335 } else { |
(...skipping 1617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1951 | 1953 |
1952 | 1954 |
1953 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { | 1955 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { |
1954 // Mark the heap roots including global variables, stack variables, | 1956 // Mark the heap roots including global variables, stack variables, |
1955 // etc., and all objects reachable from them. | 1957 // etc., and all objects reachable from them. |
1956 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); | 1958 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); |
1957 | 1959 |
1958 // Handle the string table specially. | 1960 // Handle the string table specially. |
1959 MarkStringTable(visitor); | 1961 MarkStringTable(visitor); |
1960 | 1962 |
1961 MarkWeakObjectToCodeTable(); | |
1962 | |
1963 // There may be overflowed objects in the heap. Visit them now. | 1963 // There may be overflowed objects in the heap. Visit them now. |
1964 while (marking_deque_.overflowed()) { | 1964 while (marking_deque_.overflowed()) { |
1965 RefillMarkingDeque(); | 1965 RefillMarkingDeque(); |
1966 EmptyMarkingDeque(); | 1966 EmptyMarkingDeque(); |
1967 } | 1967 } |
1968 } | 1968 } |
1969 | 1969 |
1970 | 1970 |
1971 void MarkCompactCollector::MarkImplicitRefGroups() { | 1971 void MarkCompactCollector::MarkImplicitRefGroups() { |
1972 List<ImplicitRefGroup*>* ref_groups = | 1972 List<ImplicitRefGroup*>* ref_groups = |
(...skipping 20 matching lines...) Expand all Loading... | |
1993 } | 1993 } |
1994 | 1994 |
1995 // Once the entire group has been marked, dispose it because it's | 1995 // Once the entire group has been marked, dispose it because it's |
1996 // not needed anymore. | 1996 // not needed anymore. |
1997 delete entry; | 1997 delete entry; |
1998 } | 1998 } |
1999 ref_groups->Rewind(last); | 1999 ref_groups->Rewind(last); |
2000 } | 2000 } |
2001 | 2001 |
2002 | 2002 |
2003 void MarkCompactCollector::MarkWeakObjectToCodeTable() { | |
2004 HeapObject* weak_object_to_code_table = | |
2005 HeapObject::cast(heap()->weak_object_to_code_table()); | |
2006 if (!IsMarked(weak_object_to_code_table)) { | |
2007 MarkBit mark = Marking::MarkBitFrom(weak_object_to_code_table); | |
2008 SetMark(weak_object_to_code_table, mark); | |
2009 } | |
2010 } | |
2011 | |
2012 | |
2013 // Mark all objects reachable from the objects on the marking stack. | 2003 // Mark all objects reachable from the objects on the marking stack. |
2014 // Before: the marking stack contains zero or more heap object pointers. | 2004 // Before: the marking stack contains zero or more heap object pointers. |
2015 // After: the marking stack is empty, and all objects reachable from the | 2005 // After: the marking stack is empty, and all objects reachable from the |
2016 // marking stack have been marked, or are overflowed in the heap. | 2006 // marking stack have been marked, or are overflowed in the heap. |
2017 void MarkCompactCollector::EmptyMarkingDeque() { | 2007 void MarkCompactCollector::EmptyMarkingDeque() { |
2018 Map* filler_map = heap_->one_pointer_filler_map(); | 2008 Map* filler_map = heap_->one_pointer_filler_map(); |
2019 while (!marking_deque_.IsEmpty()) { | 2009 while (!marking_deque_.IsEmpty()) { |
2020 HeapObject* object = marking_deque_.Pop(); | 2010 HeapObject* object = marking_deque_.Pop(); |
2021 // Explicitly skip one word fillers. Incremental markbit patterns are | 2011 // Explicitly skip one word fillers. Incremental markbit patterns are |
2022 // correct only for objects that occupy at least two words. | 2012 // correct only for objects that occupy at least two words. |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2321 for (HeapObject* obj = map_iterator.Next(); obj != NULL; | 2311 for (HeapObject* obj = map_iterator.Next(); obj != NULL; |
2322 obj = map_iterator.Next()) { | 2312 obj = map_iterator.Next()) { |
2323 Map* map = Map::cast(obj); | 2313 Map* map = Map::cast(obj); |
2324 | 2314 |
2325 if (!map->CanTransition()) continue; | 2315 if (!map->CanTransition()) continue; |
2326 | 2316 |
2327 MarkBit map_mark = Marking::MarkBitFrom(map); | 2317 MarkBit map_mark = Marking::MarkBitFrom(map); |
2328 ClearNonLivePrototypeTransitions(map); | 2318 ClearNonLivePrototypeTransitions(map); |
2329 ClearNonLiveMapTransitions(map, map_mark); | 2319 ClearNonLiveMapTransitions(map, map_mark); |
2330 | 2320 |
2331 if (map_mark.Get()) { | 2321 if (!map_mark.Get()) { |
2332 ClearNonLiveDependentCode(map->dependent_code()); | 2322 have_code_to_deoptimize_ |= |
2333 } else { | 2323 map->dependent_code()->MarkCodeForDeoptimization( |
2334 ClearDependentCode(map->dependent_code()); | 2324 isolate(), DependentCode::kWeakCodeGroup); |
2335 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array())); | 2325 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array())); |
2336 } | 2326 } |
2337 } | 2327 } |
2338 | 2328 |
2339 // Iterate over property cell space, removing dependent code that is not | 2329 WeakHashTable* table = heap_->weak_object_to_code_table(); |
2340 // otherwise kept alive by strong references. | 2330 uint32_t capacity = table->Capacity(); |
2341 HeapObjectIterator cell_iterator(heap_->property_cell_space()); | 2331 for (uint32_t i = 0; i < capacity; i++) { |
2342 for (HeapObject* cell = cell_iterator.Next(); cell != NULL; | 2332 uint32_t key_index = table->EntryToIndex(i); |
2343 cell = cell_iterator.Next()) { | 2333 Object* key = table->get(key_index); |
2344 if (IsMarked(cell)) { | 2334 if (!table->IsKey(key)) continue; |
2345 ClearNonLiveDependentCode(PropertyCell::cast(cell)->dependent_code()); | 2335 uint32_t value_index = table->EntryToValueIndex(i); |
2346 } | 2336 Object* value = table->get(value_index); |
2347 } | 2337 if (WeakCell::cast(key)->cleared()) { |
2348 | 2338 have_code_to_deoptimize_ |= |
2349 // Iterate over allocation sites, removing dependent code that is not | 2339 DependentCode::cast(value)->MarkCodeForDeoptimization( |
2350 // otherwise kept alive by strong references. | 2340 isolate(), DependentCode::kWeakCodeGroup); |
2351 Object* undefined = heap()->undefined_value(); | 2341 table->set(key_index, heap_->the_hole_value()); |
2352 for (Object* site = heap()->allocation_sites_list(); site != undefined; | 2342 table->set(value_index, heap_->the_hole_value()); |
2353 site = AllocationSite::cast(site)->weak_next()) { | 2343 table->ElementRemoved(); |
2354 if (IsMarked(site)) { | |
2355 ClearNonLiveDependentCode(AllocationSite::cast(site)->dependent_code()); | |
2356 } | |
2357 } | |
2358 | |
2359 if (heap_->weak_object_to_code_table()->IsHashTable()) { | |
2360 WeakHashTable* table = | |
2361 WeakHashTable::cast(heap_->weak_object_to_code_table()); | |
2362 uint32_t capacity = table->Capacity(); | |
2363 for (uint32_t i = 0; i < capacity; i++) { | |
2364 uint32_t key_index = table->EntryToIndex(i); | |
2365 Object* key = table->get(key_index); | |
2366 if (!table->IsKey(key)) continue; | |
2367 uint32_t value_index = table->EntryToValueIndex(i); | |
2368 Object* value = table->get(value_index); | |
2369 if (key->IsCell() && !IsMarked(key)) { | |
2370 Cell* cell = Cell::cast(key); | |
2371 Object* object = cell->value(); | |
2372 if (IsMarked(object)) { | |
2373 MarkBit mark = Marking::MarkBitFrom(cell); | |
2374 SetMark(cell, mark); | |
2375 Object** value_slot = HeapObject::RawField(cell, Cell::kValueOffset); | |
2376 RecordSlot(value_slot, value_slot, *value_slot); | |
2377 } | |
2378 } | |
2379 if (IsMarked(key)) { | |
2380 if (!IsMarked(value)) { | |
2381 HeapObject* obj = HeapObject::cast(value); | |
2382 MarkBit mark = Marking::MarkBitFrom(obj); | |
2383 SetMark(obj, mark); | |
2384 } | |
2385 ClearNonLiveDependentCode(DependentCode::cast(value)); | |
2386 } else { | |
2387 ClearDependentCode(DependentCode::cast(value)); | |
2388 table->set(key_index, heap_->the_hole_value()); | |
2389 table->set(value_index, heap_->the_hole_value()); | |
2390 table->ElementRemoved(); | |
2391 } | |
2392 } | 2344 } |
2393 } | 2345 } |
2394 } | 2346 } |
2395 | 2347 |
2396 | 2348 |
2397 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { | 2349 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { |
2398 int number_of_transitions = map->NumberOfProtoTransitions(); | 2350 int number_of_transitions = map->NumberOfProtoTransitions(); |
2399 FixedArray* prototype_transitions = map->GetPrototypeTransitions(); | 2351 FixedArray* prototype_transitions = map->GetPrototypeTransitions(); |
2400 | 2352 |
2401 int new_number_of_transitions = 0; | 2353 int new_number_of_transitions = 0; |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2553 if (to_trim <= 0) return; | 2505 if (to_trim <= 0) return; |
2554 heap_->RightTrimFixedArray<Heap::FROM_GC>(descriptors->GetEnumCache(), | 2506 heap_->RightTrimFixedArray<Heap::FROM_GC>(descriptors->GetEnumCache(), |
2555 to_trim); | 2507 to_trim); |
2556 | 2508 |
2557 if (!descriptors->HasEnumIndicesCache()) return; | 2509 if (!descriptors->HasEnumIndicesCache()) return; |
2558 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache(); | 2510 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache(); |
2559 heap_->RightTrimFixedArray<Heap::FROM_GC>(enum_indices_cache, to_trim); | 2511 heap_->RightTrimFixedArray<Heap::FROM_GC>(enum_indices_cache, to_trim); |
2560 } | 2512 } |
2561 | 2513 |
2562 | 2514 |
2563 void MarkCompactCollector::ClearDependentCode(DependentCode* entries) { | |
2564 DisallowHeapAllocation no_allocation; | |
2565 DependentCode::GroupStartIndexes starts(entries); | |
2566 int number_of_entries = starts.number_of_entries(); | |
2567 if (number_of_entries == 0) return; | |
2568 int g = DependentCode::kWeakCodeGroup; | |
2569 for (int i = starts.at(g); i < starts.at(g + 1); i++) { | |
2570 // If the entry is compilation info then the map must be alive, | |
2571 // and ClearDependentCode shouldn't be called. | |
2572 DCHECK(entries->is_code_at(i)); | |
2573 Code* code = entries->code_at(i); | |
2574 if (IsMarked(code) && !code->marked_for_deoptimization()) { | |
2575 DependentCode::SetMarkedForDeoptimization( | |
2576 code, static_cast<DependentCode::DependencyGroup>(g)); | |
2577 code->InvalidateEmbeddedObjects(); | |
2578 have_code_to_deoptimize_ = true; | |
2579 } | |
2580 } | |
2581 for (int i = 0; i < number_of_entries; i++) { | |
2582 entries->clear_at(i); | |
2583 } | |
2584 } | |
2585 | |
2586 | |
2587 int MarkCompactCollector::ClearNonLiveDependentCodeInGroup( | |
2588 DependentCode* entries, int group, int start, int end, int new_start) { | |
2589 int survived = 0; | |
2590 for (int i = start; i < end; i++) { | |
2591 Object* obj = entries->object_at(i); | |
2592 DCHECK(obj->IsCode() || IsMarked(obj)); | |
2593 if (IsMarked(obj) && | |
2594 (!obj->IsCode() || !WillBeDeoptimized(Code::cast(obj)))) { | |
2595 if (new_start + survived != i) { | |
2596 entries->set_object_at(new_start + survived, obj); | |
2597 } | |
2598 Object** slot = entries->slot_at(new_start + survived); | |
2599 RecordSlot(slot, slot, obj); | |
2600 survived++; | |
2601 } | |
2602 } | |
2603 entries->set_number_of_entries( | |
2604 static_cast<DependentCode::DependencyGroup>(group), survived); | |
2605 return survived; | |
2606 } | |
2607 | |
2608 | |
2609 void MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) { | |
2610 DisallowHeapAllocation no_allocation; | |
2611 DependentCode::GroupStartIndexes starts(entries); | |
2612 int number_of_entries = starts.number_of_entries(); | |
2613 if (number_of_entries == 0) return; | |
2614 int new_number_of_entries = 0; | |
2615 // Go through all groups, remove dead codes and compact. | |
2616 for (int g = 0; g < DependentCode::kGroupCount; g++) { | |
2617 int survived = ClearNonLiveDependentCodeInGroup( | |
2618 entries, g, starts.at(g), starts.at(g + 1), new_number_of_entries); | |
2619 new_number_of_entries += survived; | |
2620 } | |
2621 for (int i = new_number_of_entries; i < number_of_entries; i++) { | |
2622 entries->clear_at(i); | |
2623 } | |
2624 } | |
2625 | |
2626 | |
2627 void MarkCompactCollector::ProcessWeakCollections() { | 2515 void MarkCompactCollector::ProcessWeakCollections() { |
2628 GCTracer::Scope gc_scope(heap()->tracer(), | 2516 GCTracer::Scope gc_scope(heap()->tracer(), |
2629 GCTracer::Scope::MC_WEAKCOLLECTION_PROCESS); | 2517 GCTracer::Scope::MC_WEAKCOLLECTION_PROCESS); |
2630 Object* weak_collection_obj = heap()->encountered_weak_collections(); | 2518 Object* weak_collection_obj = heap()->encountered_weak_collections(); |
2631 while (weak_collection_obj != Smi::FromInt(0)) { | 2519 while (weak_collection_obj != Smi::FromInt(0)) { |
2632 JSWeakCollection* weak_collection = | 2520 JSWeakCollection* weak_collection = |
2633 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); | 2521 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); |
2634 DCHECK(MarkCompactCollector::IsMarked(weak_collection)); | 2522 DCHECK(MarkCompactCollector::IsMarked(weak_collection)); |
2635 if (weak_collection->table()->IsHashTable()) { | 2523 if (weak_collection->table()->IsHashTable()) { |
2636 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); | 2524 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2692 | 2580 |
2693 void MarkCompactCollector::ProcessAndClearWeakCells() { | 2581 void MarkCompactCollector::ProcessAndClearWeakCells() { |
2694 HeapObject* undefined = heap()->undefined_value(); | 2582 HeapObject* undefined = heap()->undefined_value(); |
2695 Object* weak_cell_obj = heap()->encountered_weak_cells(); | 2583 Object* weak_cell_obj = heap()->encountered_weak_cells(); |
2696 while (weak_cell_obj != Smi::FromInt(0)) { | 2584 while (weak_cell_obj != Smi::FromInt(0)) { |
2697 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); | 2585 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); |
2698 // We do not insert cleared weak cells into the list, so the value | 2586 // We do not insert cleared weak cells into the list, so the value |
2699 // cannot be a Smi here. | 2587 // cannot be a Smi here. |
2700 HeapObject* value = HeapObject::cast(weak_cell->value()); | 2588 HeapObject* value = HeapObject::cast(weak_cell->value()); |
2701 if (!MarkCompactCollector::IsMarked(value)) { | 2589 if (!MarkCompactCollector::IsMarked(value)) { |
2702 weak_cell->clear(); | 2590 // Cells for new-space objects embedded in optimized code are wrapped in |
2591 // WeakCell and put into Heap::weak_object_to_code_table. | |
2592 // Such cells do not have any strong references but we want to keep them | |
2593 // alive as long as the cell value is alive. | |
2594 // TODO(ulan): remove this once we remove Heap::weak_object_to_code_table. | |
2595 if (value->IsCell()) { | |
2596 Object* cell_value = Cell::cast(value)->value(); | |
2597 if (cell_value->IsHeapObject() && | |
2598 MarkCompactCollector::IsMarked(HeapObject::cast(cell_value))) { | |
2599 // Resurrect the cell. | |
2600 MarkBit mark = Marking::MarkBitFrom(value); | |
2601 SetMark(value, mark); | |
2602 Object** slot = HeapObject::RawField(value, Cell::kValueOffset); | |
2603 RecordSlot(slot, slot, *slot); | |
2604 slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset); | |
2605 RecordSlot(slot, slot, *slot); | |
2606 } else { | |
2607 weak_cell->clear(); | |
2608 } | |
2609 } else { | |
2610 weak_cell->clear(); | |
2611 } | |
2703 } else { | 2612 } else { |
2704 Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset); | 2613 Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset); |
2705 heap()->mark_compact_collector()->RecordSlot(slot, slot, value); | 2614 RecordSlot(slot, slot, *slot); |
2706 } | 2615 } |
2707 weak_cell_obj = weak_cell->next(); | 2616 weak_cell_obj = weak_cell->next(); |
2708 weak_cell->set_next(undefined, SKIP_WRITE_BARRIER); | 2617 weak_cell->set_next(undefined, SKIP_WRITE_BARRIER); |
2709 } | 2618 } |
2710 heap()->set_encountered_weak_cells(Smi::FromInt(0)); | 2619 heap()->set_encountered_weak_cells(Smi::FromInt(0)); |
2711 } | 2620 } |
2712 | 2621 |
2713 | 2622 |
2714 void MarkCompactCollector::AbortWeakCells() { | 2623 void MarkCompactCollector::AbortWeakCells() { |
2715 Object* undefined = heap()->undefined_value(); | 2624 Object* undefined = heap()->undefined_value(); |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3541 HeapObjectIterator js_global_property_cell_iterator( | 3450 HeapObjectIterator js_global_property_cell_iterator( |
3542 heap_->property_cell_space()); | 3451 heap_->property_cell_space()); |
3543 for (HeapObject* cell = js_global_property_cell_iterator.Next(); cell != NULL; | 3452 for (HeapObject* cell = js_global_property_cell_iterator.Next(); cell != NULL; |
3544 cell = js_global_property_cell_iterator.Next()) { | 3453 cell = js_global_property_cell_iterator.Next()) { |
3545 if (cell->IsPropertyCell()) { | 3454 if (cell->IsPropertyCell()) { |
3546 PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor); | 3455 PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor); |
3547 } | 3456 } |
3548 } | 3457 } |
3549 | 3458 |
3550 heap_->string_table()->Iterate(&updating_visitor); | 3459 heap_->string_table()->Iterate(&updating_visitor); |
3551 updating_visitor.VisitPointer(heap_->weak_object_to_code_table_address()); | |
3552 if (heap_->weak_object_to_code_table()->IsHashTable()) { | |
3553 WeakHashTable* table = | |
3554 WeakHashTable::cast(heap_->weak_object_to_code_table()); | |
3555 table->Iterate(&updating_visitor); | |
3556 table->Rehash(heap_->isolate()->factory()->undefined_value()); | |
3557 } | |
3558 | 3460 |
3559 // Update pointers from external string table. | 3461 // Update pointers from external string table. |
3560 heap_->UpdateReferencesInExternalStringTable( | 3462 heap_->UpdateReferencesInExternalStringTable( |
3561 &UpdateReferenceInExternalStringTableEntry); | 3463 &UpdateReferenceInExternalStringTableEntry); |
3562 | 3464 |
3563 EvacuationWeakObjectRetainer evacuation_object_retainer; | 3465 EvacuationWeakObjectRetainer evacuation_object_retainer; |
3564 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); | 3466 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); |
3565 | 3467 |
3566 // Collects callback info for handles that are pending (about to be | 3468 // Collects callback info for handles that are pending (about to be |
3567 // collected) and either phantom or internal-fields. Releases the global | 3469 // collected) and either phantom or internal-fields. Releases the global |
3568 // handles. See also PostGarbageCollectionProcessing. | 3470 // handles. See also PostGarbageCollectionProcessing. |
3569 isolate()->global_handles()->CollectAllPhantomCallbackData(); | 3471 isolate()->global_handles()->CollectAllPhantomCallbackData(); |
3570 | 3472 |
3571 // Visit invalidated code (we ignored all slots on it) and clear mark-bits | 3473 // Visit invalidated code (we ignored all slots on it) and clear mark-bits |
3572 // under it. | 3474 // under it. |
3573 ProcessInvalidatedCode(&updating_visitor); | 3475 ProcessInvalidatedCode(&updating_visitor); |
3574 | 3476 |
3575 heap_->isolate()->inner_pointer_to_code_cache()->Flush(); | 3477 heap_->isolate()->inner_pointer_to_code_cache()->Flush(); |
3576 | 3478 |
3577 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); | 3479 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); |
3578 DCHECK(migration_slots_buffer_ == NULL); | 3480 DCHECK(migration_slots_buffer_ == NULL); |
3481 | |
3482 // The hashing of weak_object_to_code_table is no longer valid. | |
3483 heap()->weak_object_to_code_table()->Rehash( | |
3484 heap()->isolate()->factory()->undefined_value()); | |
3579 } | 3485 } |
3580 | 3486 |
3581 | 3487 |
3582 void MarkCompactCollector::MoveEvacuationCandidatesToEndOfPagesList() { | 3488 void MarkCompactCollector::MoveEvacuationCandidatesToEndOfPagesList() { |
3583 int npages = evacuation_candidates_.length(); | 3489 int npages = evacuation_candidates_.length(); |
3584 for (int i = 0; i < npages; i++) { | 3490 for (int i = 0; i < npages; i++) { |
3585 Page* p = evacuation_candidates_[i]; | 3491 Page* p = evacuation_candidates_[i]; |
3586 if (!p->IsEvacuationCandidate()) continue; | 3492 if (!p->IsEvacuationCandidate()) continue; |
3587 p->Unlink(); | 3493 p->Unlink(); |
3588 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); | 3494 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4423 SlotsBuffer* buffer = *buffer_address; | 4329 SlotsBuffer* buffer = *buffer_address; |
4424 while (buffer != NULL) { | 4330 while (buffer != NULL) { |
4425 SlotsBuffer* next_buffer = buffer->next(); | 4331 SlotsBuffer* next_buffer = buffer->next(); |
4426 DeallocateBuffer(buffer); | 4332 DeallocateBuffer(buffer); |
4427 buffer = next_buffer; | 4333 buffer = next_buffer; |
4428 } | 4334 } |
4429 *buffer_address = NULL; | 4335 *buffer_address = NULL; |
4430 } | 4336 } |
4431 } | 4337 } |
4432 } // namespace v8::internal | 4338 } // namespace v8::internal |
OLD | NEW |