OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 if (!FLAG_collect_maps) ReattachInitialMaps(); | 442 if (!FLAG_collect_maps) ReattachInitialMaps(); |
443 | 443 |
444 #ifdef DEBUG | 444 #ifdef DEBUG |
445 if (FLAG_verify_native_context_separation) { | 445 if (FLAG_verify_native_context_separation) { |
446 VerifyNativeContextSeparation(heap_); | 446 VerifyNativeContextSeparation(heap_); |
447 } | 447 } |
448 #endif | 448 #endif |
449 | 449 |
450 #ifdef VERIFY_HEAP | 450 #ifdef VERIFY_HEAP |
451 if (heap()->weak_embedded_objects_verification_enabled()) { | 451 if (heap()->weak_embedded_objects_verification_enabled()) { |
452 VerifyWeakEmbeddedObjectsInOptimizedCode(); | 452 VerifyWeakEmbeddedObjectsInCode(); |
453 } | 453 } |
454 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) { | 454 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) { |
455 VerifyOmittedMapChecks(); | 455 VerifyOmittedMapChecks(); |
456 } | 456 } |
457 #endif | 457 #endif |
458 | 458 |
459 Finish(); | 459 Finish(); |
460 | 460 |
461 if (marking_parity_ == EVEN_MARKING_PARITY) { | 461 if (marking_parity_ == EVEN_MARKING_PARITY) { |
462 marking_parity_ = ODD_MARKING_PARITY; | 462 marking_parity_ = ODD_MARKING_PARITY; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 | 503 |
504 LargeObjectIterator it(heap_->lo_space()); | 504 LargeObjectIterator it(heap_->lo_space()); |
505 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 505 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
506 MarkBit mark_bit = Marking::MarkBitFrom(obj); | 506 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
507 CHECK(Marking::IsWhite(mark_bit)); | 507 CHECK(Marking::IsWhite(mark_bit)); |
508 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); | 508 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); |
509 } | 509 } |
510 } | 510 } |
511 | 511 |
512 | 512 |
513 void MarkCompactCollector::VerifyWeakEmbeddedObjectsInOptimizedCode() { | 513 void MarkCompactCollector::VerifyWeakEmbeddedObjectsInCode() { |
514 HeapObjectIterator code_iterator(heap()->code_space()); | 514 HeapObjectIterator code_iterator(heap()->code_space()); |
515 for (HeapObject* obj = code_iterator.Next(); | 515 for (HeapObject* obj = code_iterator.Next(); |
516 obj != NULL; | 516 obj != NULL; |
517 obj = code_iterator.Next()) { | 517 obj = code_iterator.Next()) { |
518 Code* code = Code::cast(obj); | 518 Code* code = Code::cast(obj); |
519 if (code->kind() != Code::OPTIMIZED_FUNCTION) continue; | 519 if (!code->is_optimized_code() && !code->is_weak_stub()) continue; |
520 if (WillBeDeoptimized(code)) continue; | 520 if (WillBeDeoptimized(code)) continue; |
521 code->VerifyEmbeddedObjectsDependency(); | 521 code->VerifyEmbeddedObjectsDependency(); |
522 } | 522 } |
523 } | 523 } |
524 | 524 |
525 | 525 |
526 void MarkCompactCollector::VerifyOmittedMapChecks() { | 526 void MarkCompactCollector::VerifyOmittedMapChecks() { |
527 HeapObjectIterator iterator(heap()->map_space()); | 527 HeapObjectIterator iterator(heap()->map_space()); |
528 for (HeapObject* obj = iterator.Next(); | 528 for (HeapObject* obj = iterator.Next(); |
529 obj != NULL; | 529 obj != NULL; |
(...skipping 2045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2575 // from SharedFunctionInfo during the mark phase. | 2575 // from SharedFunctionInfo during the mark phase. |
2576 // Since it survived the GC, reattach it now. | 2576 // Since it survived the GC, reattach it now. |
2577 JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); | 2577 JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); |
2578 } | 2578 } |
2579 | 2579 |
2580 ClearNonLivePrototypeTransitions(map); | 2580 ClearNonLivePrototypeTransitions(map); |
2581 ClearNonLiveMapTransitions(map, map_mark); | 2581 ClearNonLiveMapTransitions(map, map_mark); |
2582 | 2582 |
2583 if (map_mark.Get()) { | 2583 if (map_mark.Get()) { |
2584 ClearNonLiveDependentCode(map->dependent_code()); | 2584 ClearNonLiveDependentCode(map->dependent_code()); |
| 2585 ClearNonLiveDependentIC(map); |
2585 } else { | 2586 } else { |
2586 ClearAndDeoptimizeDependentCode(map->dependent_code()); | 2587 ClearAndDeoptimizeDependentCode(map->dependent_code()); |
2587 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array())); | 2588 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array())); |
| 2589 ClearAndInvalidateDependentIC(map); |
2588 } | 2590 } |
2589 } | 2591 } |
2590 | 2592 |
2591 // Iterate over property cell space, removing dependent code that is not | 2593 // Iterate over property cell space, removing dependent code that is not |
2592 // otherwise kept alive by strong references. | 2594 // otherwise kept alive by strong references. |
2593 HeapObjectIterator cell_iterator(heap_->property_cell_space()); | 2595 HeapObjectIterator cell_iterator(heap_->property_cell_space()); |
2594 for (HeapObject* cell = cell_iterator.Next(); | 2596 for (HeapObject* cell = cell_iterator.Next(); |
2595 cell != NULL; | 2597 cell != NULL; |
2596 cell = cell_iterator.Next()) { | 2598 cell = cell_iterator.Next()) { |
2597 if (IsMarked(cell)) { | 2599 if (IsMarked(cell)) { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2758 static_cast<DependentCode::DependencyGroup>(g), | 2760 static_cast<DependentCode::DependencyGroup>(g), |
2759 group_number_of_entries); | 2761 group_number_of_entries); |
2760 new_number_of_entries += group_number_of_entries; | 2762 new_number_of_entries += group_number_of_entries; |
2761 } | 2763 } |
2762 for (int i = new_number_of_entries; i < number_of_entries; i++) { | 2764 for (int i = new_number_of_entries; i < number_of_entries; i++) { |
2763 entries->clear_at(i); | 2765 entries->clear_at(i); |
2764 } | 2766 } |
2765 } | 2767 } |
2766 | 2768 |
2767 | 2769 |
| 2770 void MarkCompactCollector::ClearAndInvalidateDependentIC(Map* map) { |
| 2771 Object* current = map->dependent_ic(); |
| 2772 Object* undefined = heap()->undefined_value(); |
| 2773 while (current != undefined) { |
| 2774 Code* code = Code::cast(current); |
| 2775 if (IsMarked(code)) { |
| 2776 ASSERT(code->is_weak_stub()); |
| 2777 IC::InvalidateMaps(code); |
| 2778 } |
| 2779 current = code->next_code_link(); |
| 2780 code->set_next_code_link(undefined); |
| 2781 } |
| 2782 map->set_dependent_ic(undefined); |
| 2783 } |
| 2784 |
| 2785 |
| 2786 void MarkCompactCollector::ClearNonLiveDependentIC(Map* map) { |
| 2787 MarkCompactWeakObjectRetainer retainer; |
| 2788 Object* head = |
| 2789 VisitWeakList<Code>(heap(), map->dependent_ic(), &retainer, true); |
| 2790 map->set_dependent_ic(head); |
| 2791 Object** slot = HeapObject::RawField(map, Map::kDependentICOffset); |
| 2792 RecordSlot(slot, slot, head); |
| 2793 } |
| 2794 |
| 2795 |
2768 void MarkCompactCollector::ProcessWeakCollections() { | 2796 void MarkCompactCollector::ProcessWeakCollections() { |
2769 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKCOLLECTION_PROCESS); | 2797 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKCOLLECTION_PROCESS); |
2770 Object* weak_collection_obj = encountered_weak_collections(); | 2798 Object* weak_collection_obj = encountered_weak_collections(); |
2771 while (weak_collection_obj != Smi::FromInt(0)) { | 2799 while (weak_collection_obj != Smi::FromInt(0)) { |
2772 ASSERT(MarkCompactCollector::IsMarked( | 2800 ASSERT(MarkCompactCollector::IsMarked( |
2773 HeapObject::cast(weak_collection_obj))); | 2801 HeapObject::cast(weak_collection_obj))); |
2774 JSWeakCollection* weak_collection = | 2802 JSWeakCollection* weak_collection = |
2775 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); | 2803 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); |
2776 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); | 2804 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); |
2777 Object** anchor = reinterpret_cast<Object**>(table->address()); | 2805 Object** anchor = reinterpret_cast<Object**>(table->address()); |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3402 MarkBit mark_bit = Marking::MarkBitFrom(code); | 3430 MarkBit mark_bit = Marking::MarkBitFrom(code); |
3403 if (Marking::IsWhite(mark_bit)) return; | 3431 if (Marking::IsWhite(mark_bit)) return; |
3404 | 3432 |
3405 invalidated_code_.Add(code); | 3433 invalidated_code_.Add(code); |
3406 } | 3434 } |
3407 } | 3435 } |
3408 | 3436 |
3409 | 3437 |
3410 // Return true if the given code is deoptimized or will be deoptimized. | 3438 // Return true if the given code is deoptimized or will be deoptimized. |
3411 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { | 3439 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { |
3412 return code->marked_for_deoptimization(); | 3440 return code->is_optimized_code() && code->marked_for_deoptimization(); |
3413 } | 3441 } |
3414 | 3442 |
3415 | 3443 |
3416 bool MarkCompactCollector::MarkInvalidatedCode() { | 3444 bool MarkCompactCollector::MarkInvalidatedCode() { |
3417 bool code_marked = false; | 3445 bool code_marked = false; |
3418 | 3446 |
3419 int length = invalidated_code_.length(); | 3447 int length = invalidated_code_.length(); |
3420 for (int i = 0; i < length; i++) { | 3448 for (int i = 0; i < length; i++) { |
3421 Code* code = invalidated_code_[i]; | 3449 Code* code = invalidated_code_[i]; |
3422 | 3450 |
(...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4524 while (buffer != NULL) { | 4552 while (buffer != NULL) { |
4525 SlotsBuffer* next_buffer = buffer->next(); | 4553 SlotsBuffer* next_buffer = buffer->next(); |
4526 DeallocateBuffer(buffer); | 4554 DeallocateBuffer(buffer); |
4527 buffer = next_buffer; | 4555 buffer = next_buffer; |
4528 } | 4556 } |
4529 *buffer_address = NULL; | 4557 *buffer_address = NULL; |
4530 } | 4558 } |
4531 | 4559 |
4532 | 4560 |
4533 } } // namespace v8::internal | 4561 } } // namespace v8::internal |
OLD | NEW |