| 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 |