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 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
840 } | 840 } |
841 | 841 |
842 static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) { | 842 static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) { |
843 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); | 843 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); |
844 JSGlobalPropertyCell* cell = | 844 JSGlobalPropertyCell* cell = |
845 JSGlobalPropertyCell::cast(rinfo->target_cell()); | 845 JSGlobalPropertyCell::cast(rinfo->target_cell()); |
846 MarkBit mark = Marking::MarkBitFrom(cell); | 846 MarkBit mark = Marking::MarkBitFrom(cell); |
847 heap->mark_compact_collector()->MarkObject(cell, mark); | 847 heap->mark_compact_collector()->MarkObject(cell, mark); |
848 } | 848 } |
849 | 849 |
850 static inline void VisitEmbeddedPointer(Heap* heap, Code* host, Object** p) { | 850 static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo) { |
851 MarkObjectByPointer(heap->mark_compact_collector(), | 851 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
852 reinterpret_cast<Object**>(host), | 852 // TODO(mstarzinger): We do not short-circuit cons strings here, verify |
853 p); | 853 // that there can be no such embedded pointers and add assertion here. |
| 854 HeapObject* object = HeapObject::cast(rinfo->target_object()); |
| 855 heap->mark_compact_collector()->RecordRelocSlot(rinfo, object); |
| 856 MarkBit mark = Marking::MarkBitFrom(object); |
| 857 heap->mark_compact_collector()->MarkObject(object, mark); |
854 } | 858 } |
855 | 859 |
856 static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { | 860 static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { |
857 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 861 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
858 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 862 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
859 if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()) { | 863 if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()) { |
860 IC::Clear(rinfo->pc()); | 864 IC::Clear(rinfo->pc()); |
861 // Please note targets for cleared inline cached do not have to be | 865 // Please note targets for cleared inline cached do not have to be |
862 // marked since they are contained in HEAP->non_monomorphic_cache(). | 866 // marked since they are contained in HEAP->non_monomorphic_cache(). |
863 target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 867 target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
(...skipping 1587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2451 explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) { } | 2455 explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) { } |
2452 | 2456 |
2453 void VisitPointer(Object** p) { | 2457 void VisitPointer(Object** p) { |
2454 UpdatePointer(p); | 2458 UpdatePointer(p); |
2455 } | 2459 } |
2456 | 2460 |
2457 void VisitPointers(Object** start, Object** end) { | 2461 void VisitPointers(Object** start, Object** end) { |
2458 for (Object** p = start; p < end; p++) UpdatePointer(p); | 2462 for (Object** p = start; p < end; p++) UpdatePointer(p); |
2459 } | 2463 } |
2460 | 2464 |
2461 void VisitEmbeddedPointer(Code* host, Object** p) { | 2465 void VisitEmbeddedPointer(RelocInfo* rinfo) { |
2462 UpdatePointer(p); | 2466 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
| 2467 Object* target = rinfo->target_object(); |
| 2468 VisitPointer(&target); |
| 2469 rinfo->set_target_object(target); |
2463 } | 2470 } |
2464 | 2471 |
2465 void VisitCodeTarget(RelocInfo* rinfo) { | 2472 void VisitCodeTarget(RelocInfo* rinfo) { |
2466 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 2473 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
2467 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 2474 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
2468 VisitPointer(&target); | 2475 VisitPointer(&target); |
2469 rinfo->set_target_address(Code::cast(target)->instruction_start()); | 2476 rinfo->set_target_address(Code::cast(target)->instruction_start()); |
2470 } | 2477 } |
2471 | 2478 |
2472 void VisitDebugTarget(RelocInfo* rinfo) { | 2479 void VisitDebugTarget(RelocInfo* rinfo) { |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2766 case SlotsBuffer::DEBUG_TARGET_SLOT: { | 2773 case SlotsBuffer::DEBUG_TARGET_SLOT: { |
2767 RelocInfo rinfo(addr, RelocInfo::DEBUG_BREAK_SLOT, 0, NULL); | 2774 RelocInfo rinfo(addr, RelocInfo::DEBUG_BREAK_SLOT, 0, NULL); |
2768 if (rinfo.IsPatchedDebugBreakSlotSequence()) rinfo.Visit(v); | 2775 if (rinfo.IsPatchedDebugBreakSlotSequence()) rinfo.Visit(v); |
2769 break; | 2776 break; |
2770 } | 2777 } |
2771 case SlotsBuffer::JS_RETURN_SLOT: { | 2778 case SlotsBuffer::JS_RETURN_SLOT: { |
2772 RelocInfo rinfo(addr, RelocInfo::JS_RETURN, 0, NULL); | 2779 RelocInfo rinfo(addr, RelocInfo::JS_RETURN, 0, NULL); |
2773 if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(v); | 2780 if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(v); |
2774 break; | 2781 break; |
2775 } | 2782 } |
| 2783 case SlotsBuffer::EMBEDDED_OBJECT_SLOT: { |
| 2784 RelocInfo rinfo(addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL); |
| 2785 rinfo.Visit(v); |
| 2786 break; |
| 2787 } |
2776 default: | 2788 default: |
2777 UNREACHABLE(); | 2789 UNREACHABLE(); |
2778 break; | 2790 break; |
2779 } | 2791 } |
2780 } | 2792 } |
2781 | 2793 |
2782 | 2794 |
2783 enum SweepingMode { | 2795 enum SweepingMode { |
2784 SWEEP_ONLY, | 2796 SWEEP_ONLY, |
2785 SWEEP_AND_VISIT_LIVE_OBJECTS | 2797 SWEEP_AND_VISIT_LIVE_OBJECTS |
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3699 ASSERT(buffer->HasSpaceForTypedSlot()); | 3711 ASSERT(buffer->HasSpaceForTypedSlot()); |
3700 buffer->Add(reinterpret_cast<ObjectSlot>(type)); | 3712 buffer->Add(reinterpret_cast<ObjectSlot>(type)); |
3701 buffer->Add(reinterpret_cast<ObjectSlot>(addr)); | 3713 buffer->Add(reinterpret_cast<ObjectSlot>(addr)); |
3702 return true; | 3714 return true; |
3703 } | 3715 } |
3704 | 3716 |
3705 | 3717 |
3706 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { | 3718 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { |
3707 if (RelocInfo::IsCodeTarget(rmode)) { | 3719 if (RelocInfo::IsCodeTarget(rmode)) { |
3708 return SlotsBuffer::CODE_TARGET_SLOT; | 3720 return SlotsBuffer::CODE_TARGET_SLOT; |
| 3721 } else if (RelocInfo::IsEmbeddedObject(rmode)) { |
| 3722 return SlotsBuffer::EMBEDDED_OBJECT_SLOT; |
3709 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { | 3723 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { |
3710 return SlotsBuffer::DEBUG_TARGET_SLOT; | 3724 return SlotsBuffer::DEBUG_TARGET_SLOT; |
3711 } else if (RelocInfo::IsJSReturn(rmode)) { | 3725 } else if (RelocInfo::IsJSReturn(rmode)) { |
3712 return SlotsBuffer::JS_RETURN_SLOT; | 3726 return SlotsBuffer::JS_RETURN_SLOT; |
3713 } | 3727 } |
3714 UNREACHABLE(); | 3728 UNREACHABLE(); |
3715 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; | 3729 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; |
3716 } | 3730 } |
3717 | 3731 |
3718 | 3732 |
3719 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Code* target) { | 3733 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { |
3720 Page* target_page = Page::FromAddress( | 3734 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
3721 reinterpret_cast<Address>(target)); | |
3722 if (target_page->IsEvacuationCandidate() && | 3735 if (target_page->IsEvacuationCandidate() && |
3723 (rinfo->host() == NULL || | 3736 (rinfo->host() == NULL || |
3724 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { | 3737 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { |
3725 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, | 3738 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, |
3726 target_page->slots_buffer_address(), | 3739 target_page->slots_buffer_address(), |
3727 SlotTypeForRMode(rinfo->rmode()), | 3740 SlotTypeForRMode(rinfo->rmode()), |
3728 rinfo->pc(), | 3741 rinfo->pc(), |
3729 SlotsBuffer::FAIL_ON_OVERFLOW)) { | 3742 SlotsBuffer::FAIL_ON_OVERFLOW)) { |
3730 EvictEvacuationCandidate(target_page); | 3743 EvictEvacuationCandidate(target_page); |
3731 } | 3744 } |
3732 } | 3745 } |
3733 } | 3746 } |
3734 | 3747 |
3735 | 3748 |
3736 void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { | 3749 void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { |
3737 Page* target_page = Page::FromAddress( | 3750 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
3738 reinterpret_cast<Address>(target)); | |
3739 if (target_page->IsEvacuationCandidate() && | 3751 if (target_page->IsEvacuationCandidate() && |
3740 !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) { | 3752 !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) { |
3741 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, | 3753 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, |
3742 target_page->slots_buffer_address(), | 3754 target_page->slots_buffer_address(), |
3743 SlotsBuffer::CODE_ENTRY_SLOT, | 3755 SlotsBuffer::CODE_ENTRY_SLOT, |
3744 slot, | 3756 slot, |
3745 SlotsBuffer::FAIL_ON_OVERFLOW)) { | 3757 SlotsBuffer::FAIL_ON_OVERFLOW)) { |
3746 EvictEvacuationCandidate(target_page); | 3758 EvictEvacuationCandidate(target_page); |
3747 } | 3759 } |
3748 } | 3760 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3811 while (buffer != NULL) { | 3823 while (buffer != NULL) { |
3812 SlotsBuffer* next_buffer = buffer->next(); | 3824 SlotsBuffer* next_buffer = buffer->next(); |
3813 DeallocateBuffer(buffer); | 3825 DeallocateBuffer(buffer); |
3814 buffer = next_buffer; | 3826 buffer = next_buffer; |
3815 } | 3827 } |
3816 *buffer_address = NULL; | 3828 *buffer_address = NULL; |
3817 } | 3829 } |
3818 | 3830 |
3819 | 3831 |
3820 } } // namespace v8::internal | 3832 } } // namespace v8::internal |
OLD | NEW |