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()->RecordEmbeddedSlot(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 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3710 return SlotsBuffer::DEBUG_TARGET_SLOT; | 3722 return SlotsBuffer::DEBUG_TARGET_SLOT; |
3711 } else if (RelocInfo::IsJSReturn(rmode)) { | 3723 } else if (RelocInfo::IsJSReturn(rmode)) { |
3712 return SlotsBuffer::JS_RETURN_SLOT; | 3724 return SlotsBuffer::JS_RETURN_SLOT; |
3713 } | 3725 } |
3714 UNREACHABLE(); | 3726 UNREACHABLE(); |
3715 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; | 3727 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; |
3716 } | 3728 } |
3717 | 3729 |
3718 | 3730 |
3719 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Code* target) { | 3731 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Code* target) { |
3720 Page* target_page = Page::FromAddress( | 3732 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
3721 reinterpret_cast<Address>(target)); | |
3722 if (target_page->IsEvacuationCandidate() && | 3733 if (target_page->IsEvacuationCandidate() && |
3723 (rinfo->host() == NULL || | 3734 (rinfo->host() == NULL || |
3724 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { | 3735 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { |
3725 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, | 3736 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, |
3726 target_page->slots_buffer_address(), | 3737 target_page->slots_buffer_address(), |
3727 SlotTypeForRMode(rinfo->rmode()), | 3738 SlotTypeForRMode(rinfo->rmode()), |
3728 rinfo->pc(), | 3739 rinfo->pc(), |
3729 SlotsBuffer::FAIL_ON_OVERFLOW)) { | 3740 SlotsBuffer::FAIL_ON_OVERFLOW)) { |
3730 EvictEvacuationCandidate(target_page); | 3741 EvictEvacuationCandidate(target_page); |
3731 } | 3742 } |
3732 } | 3743 } |
3733 } | 3744 } |
3734 | 3745 |
3735 | 3746 |
3736 void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { | 3747 void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { |
3737 Page* target_page = Page::FromAddress( | 3748 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
3738 reinterpret_cast<Address>(target)); | |
3739 if (target_page->IsEvacuationCandidate() && | 3749 if (target_page->IsEvacuationCandidate() && |
3740 !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) { | 3750 !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) { |
3741 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, | 3751 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, |
3742 target_page->slots_buffer_address(), | 3752 target_page->slots_buffer_address(), |
3743 SlotsBuffer::CODE_ENTRY_SLOT, | 3753 SlotsBuffer::CODE_ENTRY_SLOT, |
3744 slot, | 3754 slot, |
3745 SlotsBuffer::FAIL_ON_OVERFLOW)) { | 3755 SlotsBuffer::FAIL_ON_OVERFLOW)) { |
3746 EvictEvacuationCandidate(target_page); | 3756 EvictEvacuationCandidate(target_page); |
3747 } | 3757 } |
3748 } | 3758 } |
3749 } | 3759 } |
3750 | 3760 |
3751 | 3761 |
3762 void MarkCompactCollector::RecordEmbeddedSlot(RelocInfo* rinfo, | |
Vyacheslav Egorov (Chromium)
2011/10/12 14:21:53
Why not unify with RecordRelocSlot? seems almost i
Michael Starzinger
2011/10/12 15:38:36
Done.
| |
3763 Object* target) { | |
3764 Page* object_page = Page::FromAddress(reinterpret_cast<Address>(target)); | |
3765 if (object_page->IsEvacuationCandidate() && | |
3766 !ShouldSkipEvacuationSlotRecording(rinfo->host())) { | |
3767 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, | |
3768 object_page->slots_buffer_address(), | |
3769 SlotsBuffer::EMBEDDED_OBJECT_SLOT, | |
3770 rinfo->pc(), | |
3771 SlotsBuffer::FAIL_ON_OVERFLOW)) { | |
3772 EvictEvacuationCandidate(object_page); | |
3773 } | |
3774 } | |
3775 } | |
3776 | |
3777 | |
3752 static inline SlotsBuffer::SlotType DecodeSlotType( | 3778 static inline SlotsBuffer::SlotType DecodeSlotType( |
3753 SlotsBuffer::ObjectSlot slot) { | 3779 SlotsBuffer::ObjectSlot slot) { |
3754 return static_cast<SlotsBuffer::SlotType>(reinterpret_cast<intptr_t>(slot)); | 3780 return static_cast<SlotsBuffer::SlotType>(reinterpret_cast<intptr_t>(slot)); |
3755 } | 3781 } |
3756 | 3782 |
3757 | 3783 |
3758 void SlotsBuffer::UpdateSlots(Heap* heap) { | 3784 void SlotsBuffer::UpdateSlots(Heap* heap) { |
3759 PointersUpdatingVisitor v(heap); | 3785 PointersUpdatingVisitor v(heap); |
3760 | 3786 |
3761 for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) { | 3787 for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3811 while (buffer != NULL) { | 3837 while (buffer != NULL) { |
3812 SlotsBuffer* next_buffer = buffer->next(); | 3838 SlotsBuffer* next_buffer = buffer->next(); |
3813 DeallocateBuffer(buffer); | 3839 DeallocateBuffer(buffer); |
3814 buffer = next_buffer; | 3840 buffer = next_buffer; |
3815 } | 3841 } |
3816 *buffer_address = NULL; | 3842 *buffer_address = NULL; |
3817 } | 3843 } |
3818 | 3844 |
3819 | 3845 |
3820 } } // namespace v8::internal | 3846 } } // namespace v8::internal |
OLD | NEW |