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/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.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/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 VerifyMarking(space->heap(), page->area_start(), limit); | 137 VerifyMarking(space->heap(), page->area_start(), limit); |
138 } | 138 } |
139 } | 139 } |
140 | 140 |
141 | 141 |
142 static void VerifyMarking(PagedSpace* space) { | 142 static void VerifyMarking(PagedSpace* space) { |
143 PageIterator it(space); | 143 PageIterator it(space); |
144 | 144 |
145 while (it.has_next()) { | 145 while (it.has_next()) { |
146 Page* p = it.next(); | 146 Page* p = it.next(); |
147 VerifyMarking(space->heap(), p->area_start(), p->area_end()); | 147 if (!p->IsFlagSet(Page::BLACK_PAGE)) { |
148 VerifyMarking(space->heap(), p->area_start(), p->area_end()); | |
149 } | |
ulan
2016/02/10 10:27:39
It would be great to verify coloring invariant for
Hannes Payer (out of office)
2016/02/11 18:18:07
Done.
| |
148 } | 150 } |
149 } | 151 } |
150 | 152 |
151 | 153 |
152 static void VerifyMarking(Heap* heap) { | 154 static void VerifyMarking(Heap* heap) { |
153 VerifyMarking(heap->old_space()); | 155 VerifyMarking(heap->old_space()); |
154 VerifyMarking(heap->code_space()); | 156 VerifyMarking(heap->code_space()); |
155 VerifyMarking(heap->map_space()); | 157 VerifyMarking(heap->map_space()); |
156 VerifyMarking(heap->new_space()); | 158 VerifyMarking(heap->new_space()); |
157 | 159 |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
441 map->VerifyOmittedMapChecks(); | 443 map->VerifyOmittedMapChecks(); |
442 } | 444 } |
443 } | 445 } |
444 #endif // VERIFY_HEAP | 446 #endif // VERIFY_HEAP |
445 | 447 |
446 | 448 |
447 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { | 449 static void ClearMarkbitsInPagedSpace(PagedSpace* space) { |
448 PageIterator it(space); | 450 PageIterator it(space); |
449 | 451 |
450 while (it.has_next()) { | 452 while (it.has_next()) { |
451 Bitmap::Clear(it.next()); | 453 Page* p = it.next(); |
454 Bitmap::Clear(p); | |
455 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
456 p->ClearFlag(Page::BLACK_PAGE); | |
457 } | |
452 } | 458 } |
453 } | 459 } |
454 | 460 |
455 | 461 |
456 static void ClearMarkbitsInNewSpace(NewSpace* space) { | 462 static void ClearMarkbitsInNewSpace(NewSpace* space) { |
457 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); | 463 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); |
458 | 464 |
459 while (it.has_next()) { | 465 while (it.has_next()) { |
460 Bitmap::Clear(it.next()); | 466 Bitmap::Clear(it.next()); |
461 } | 467 } |
462 } | 468 } |
463 | 469 |
464 | 470 |
465 void MarkCompactCollector::ClearMarkbits() { | 471 void MarkCompactCollector::ClearMarkbits() { |
466 ClearMarkbitsInPagedSpace(heap_->code_space()); | 472 ClearMarkbitsInPagedSpace(heap_->code_space()); |
467 ClearMarkbitsInPagedSpace(heap_->map_space()); | 473 ClearMarkbitsInPagedSpace(heap_->map_space()); |
468 ClearMarkbitsInPagedSpace(heap_->old_space()); | 474 ClearMarkbitsInPagedSpace(heap_->old_space()); |
469 ClearMarkbitsInNewSpace(heap_->new_space()); | 475 ClearMarkbitsInNewSpace(heap_->new_space()); |
470 | 476 |
471 LargeObjectIterator it(heap_->lo_space()); | 477 LargeObjectIterator it(heap_->lo_space()); |
472 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 478 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
473 Marking::MarkWhite(Marking::MarkBitFrom(obj)); | 479 Marking::MarkWhite(Marking::MarkBitFrom(obj)); |
474 Page::FromAddress(obj->address())->ResetProgressBar(); | 480 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
475 Page::FromAddress(obj->address())->ResetLiveBytes(); | 481 chunk->ResetProgressBar(); |
482 chunk->ResetLiveBytes(); | |
483 if (chunk->IsFlagSet(Page::BLACK_PAGE)) { | |
484 chunk->ClearFlag(Page::BLACK_PAGE); | |
485 } | |
476 } | 486 } |
477 } | 487 } |
478 | 488 |
479 | 489 |
480 class MarkCompactCollector::SweeperTask : public v8::Task { | 490 class MarkCompactCollector::SweeperTask : public v8::Task { |
481 public: | 491 public: |
482 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {} | 492 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {} |
483 | 493 |
484 virtual ~SweeperTask() {} | 494 virtual ~SweeperTask() {} |
485 | 495 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
574 pending_sweeper_tasks_semaphore_.Signal(); | 584 pending_sweeper_tasks_semaphore_.Signal(); |
575 return true; | 585 return true; |
576 } | 586 } |
577 | 587 |
578 | 588 |
579 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { | 589 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { |
580 // This is only used when resizing an object. | 590 // This is only used when resizing an object. |
581 DCHECK(MemoryChunk::FromAddress(old_start) == | 591 DCHECK(MemoryChunk::FromAddress(old_start) == |
582 MemoryChunk::FromAddress(new_start)); | 592 MemoryChunk::FromAddress(new_start)); |
583 | 593 |
584 if (!heap->incremental_marking()->IsMarking()) return; | 594 if (!heap->incremental_marking()->IsMarking() || |
595 Page::FromAddress(old_start)->IsFlagSet(Page::BLACK_PAGE)) | |
596 return; | |
585 | 597 |
586 // If the mark doesn't move, we don't check the color of the object. | 598 // If the mark doesn't move, we don't check the color of the object. |
587 // It doesn't matter whether the object is black, since it hasn't changed | 599 // It doesn't matter whether the object is black, since it hasn't changed |
588 // size, so the adjustment to the live data count will be zero anyway. | 600 // size, so the adjustment to the live data count will be zero anyway. |
589 if (old_start == new_start) return; | 601 if (old_start == new_start) return; |
590 | 602 |
591 MarkBit new_mark_bit = MarkBitFrom(new_start); | 603 MarkBit new_mark_bit = MarkBitFrom(new_start); |
592 MarkBit old_mark_bit = MarkBitFrom(old_start); | 604 MarkBit old_mark_bit = MarkBitFrom(old_start); |
593 | 605 |
594 #ifdef DEBUG | 606 #ifdef DEBUG |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
683 | 695 |
684 // Pairs of (live_bytes_in_page, page). | 696 // Pairs of (live_bytes_in_page, page). |
685 typedef std::pair<int, Page*> LiveBytesPagePair; | 697 typedef std::pair<int, Page*> LiveBytesPagePair; |
686 std::vector<LiveBytesPagePair> pages; | 698 std::vector<LiveBytesPagePair> pages; |
687 pages.reserve(number_of_pages); | 699 pages.reserve(number_of_pages); |
688 | 700 |
689 PageIterator it(space); | 701 PageIterator it(space); |
690 while (it.has_next()) { | 702 while (it.has_next()) { |
691 Page* p = it.next(); | 703 Page* p = it.next(); |
692 if (p->NeverEvacuate()) continue; | 704 if (p->NeverEvacuate()) continue; |
705 if (p->IsFlagSet(Page::BLACK_PAGE)) continue; | |
693 if (p->IsFlagSet(Page::POPULAR_PAGE)) { | 706 if (p->IsFlagSet(Page::POPULAR_PAGE)) { |
694 // This page had slots buffer overflow on previous GC, skip it. | 707 // This page had slots buffer overflow on previous GC, skip it. |
695 p->ClearFlag(Page::POPULAR_PAGE); | 708 p->ClearFlag(Page::POPULAR_PAGE); |
696 continue; | 709 continue; |
697 } | 710 } |
698 // Invariant: Evacuation candidates are just created when marking is | 711 // Invariant: Evacuation candidates are just created when marking is |
699 // started. This means that sweeping has finished. Furthermore, at the end | 712 // started. This means that sweeping has finished. Furthermore, at the end |
700 // of a GC all evacuation candidates are cleared and their slot buffers are | 713 // of a GC all evacuation candidates are cleared and their slot buffers are |
701 // released. | 714 // released. |
702 CHECK(!p->IsEvacuationCandidate()); | 715 CHECK(!p->IsEvacuationCandidate()); |
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1726 } | 1739 } |
1727 return false; | 1740 return false; |
1728 } | 1741 } |
1729 }; | 1742 }; |
1730 | 1743 |
1731 | 1744 |
1732 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { | 1745 void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) { |
1733 PageIterator it(space); | 1746 PageIterator it(space); |
1734 while (it.has_next()) { | 1747 while (it.has_next()) { |
1735 Page* p = it.next(); | 1748 Page* p = it.next(); |
1736 DiscoverGreyObjectsOnPage(p); | 1749 if (!p->IsFlagSet(Page::BLACK_PAGE)) { |
1737 if (marking_deque()->IsFull()) return; | 1750 DiscoverGreyObjectsOnPage(p); |
1751 if (marking_deque()->IsFull()) return; | |
1752 } | |
1738 } | 1753 } |
1739 } | 1754 } |
1740 | 1755 |
1741 | 1756 |
1742 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { | 1757 void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() { |
1743 NewSpace* space = heap()->new_space(); | 1758 NewSpace* space = heap()->new_space(); |
1744 NewSpacePageIterator it(space->bottom(), space->top()); | 1759 NewSpacePageIterator it(space->bottom(), space->top()); |
1745 while (it.has_next()) { | 1760 while (it.has_next()) { |
1746 NewSpacePage* page = it.next(); | 1761 NewSpacePage* page = it.next(); |
1747 DiscoverGreyObjectsOnPage(page); | 1762 DiscoverGreyObjectsOnPage(page); |
(...skipping 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2906 // for it. | 2921 // for it. |
2907 CHECK(large_object->IsHeapObject()); | 2922 CHECK(large_object->IsHeapObject()); |
2908 HeapObject* large_heap_object = HeapObject::cast(large_object); | 2923 HeapObject* large_heap_object = HeapObject::cast(large_object); |
2909 if (IsMarked(large_heap_object)) { | 2924 if (IsMarked(large_heap_object)) { |
2910 *out_object = large_heap_object; | 2925 *out_object = large_heap_object; |
2911 return true; | 2926 return true; |
2912 } | 2927 } |
2913 return false; | 2928 return false; |
2914 } | 2929 } |
2915 | 2930 |
2931 // If we are on a black page, we cannot find the actual object start | |
2932 // easiliy. We just return true but do not set the out_object. | |
2933 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
2934 return true; | |
2935 } | |
2936 | |
2916 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 2937 uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); |
2917 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 2938 unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; |
2918 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); | 2939 MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); |
2919 MarkBit::CellType* cells = p->markbits()->cells(); | 2940 MarkBit::CellType* cells = p->markbits()->cells(); |
2920 Address base_address = p->area_start(); | 2941 Address base_address = p->area_start(); |
2921 unsigned int base_address_cell_index = Bitmap::IndexToCell( | 2942 unsigned int base_address_cell_index = Bitmap::IndexToCell( |
2922 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); | 2943 Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); |
2923 | 2944 |
2924 // Check if the slot points to the start of an object. This can happen e.g. | 2945 // Check if the slot points to the start of an object. This can happen e.g. |
2925 // when we left trim a fixed array. Such slots are invalid and we can remove | 2946 // when we left trim a fixed array. Such slots are invalid and we can remove |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2986 // Slots pointing to the first word of an object are invalid and removed. | 3007 // Slots pointing to the first word of an object are invalid and removed. |
2987 // This can happen when we move the object header while left trimming. | 3008 // This can happen when we move the object header while left trimming. |
2988 *out_object = object; | 3009 *out_object = object; |
2989 return true; | 3010 return true; |
2990 } | 3011 } |
2991 return false; | 3012 return false; |
2992 } | 3013 } |
2993 | 3014 |
2994 | 3015 |
2995 bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) { | 3016 bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) { |
2996 // This function does not support large objects right now. | |
2997 Space* owner = p->owner(); | 3017 Space* owner = p->owner(); |
2998 if (owner == heap_->lo_space() || owner == NULL) { | 3018 if (owner == heap_->lo_space() || owner == NULL) { |
2999 Object* large_object = heap_->lo_space()->FindObject(slot); | 3019 Object* large_object = heap_->lo_space()->FindObject(slot); |
3000 // This object has to exist, otherwise we would not have recorded a slot | 3020 // This object has to exist, otherwise we would not have recorded a slot |
3001 // for it. | 3021 // for it. |
3002 CHECK(large_object->IsHeapObject()); | 3022 CHECK(large_object->IsHeapObject()); |
3003 HeapObject* large_heap_object = HeapObject::cast(large_object); | 3023 HeapObject* large_heap_object = HeapObject::cast(large_object); |
3004 if (IsMarked(large_heap_object)) { | 3024 if (IsMarked(large_heap_object)) { |
3005 return true; | 3025 return true; |
3006 } | 3026 } |
3007 return false; | 3027 return false; |
3008 } | 3028 } |
3009 | 3029 |
3030 if (p->IsFlagSet(Page::BLACK_PAGE)) return true; | |
3031 | |
3010 LiveObjectIterator<kBlackObjects> it(p); | 3032 LiveObjectIterator<kBlackObjects> it(p); |
3011 HeapObject* object = NULL; | 3033 HeapObject* object = NULL; |
3012 while ((object = it.Next()) != NULL) { | 3034 while ((object = it.Next()) != NULL) { |
3013 int size = object->Size(); | 3035 int size = object->Size(); |
3014 | 3036 |
3015 if (object->address() > slot) return false; | 3037 if (object->address() > slot) return false; |
3016 if (object->address() <= slot && slot < (object->address() + size)) { | 3038 if (object->address() <= slot && slot < (object->address() + size)) { |
3017 return true; | 3039 return true; |
3018 } | 3040 } |
3019 } | 3041 } |
3020 return false; | 3042 return false; |
3021 } | 3043 } |
3022 | 3044 |
3023 | 3045 |
3024 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { | 3046 bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { |
3025 HeapObject* object = NULL; | |
3026 // The target object is black but we don't know if the source slot is black. | 3047 // The target object is black but we don't know if the source slot is black. |
3027 // The source object could have died and the slot could be part of a free | 3048 // The source object could have died and the slot could be part of a free |
3028 // space. Find out based on mark bits if the slot is part of a live object. | 3049 // space. Find out based on mark bits if the slot is part of a live object. |
3029 if (!IsSlotInBlackObject(Page::FromAddress(slot), slot, &object)) { | 3050 Page* page = Page::FromAddress(slot); |
3051 HeapObject* object = NULL; | |
3052 if (!IsSlotInBlackObject(page, slot, &object)) { | |
3030 return false; | 3053 return false; |
3031 } | 3054 } |
3032 | 3055 |
3033 DCHECK(object != NULL); | 3056 // If the slot is on a black page, the object will be live. |
3057 DCHECK(object != NULL || page->IsFlagSet(Page::BLACK_PAGE)); | |
3058 if (page->IsFlagSet(Page::BLACK_PAGE)) { | |
3059 return true; | |
3060 } | |
3061 | |
3034 int offset = static_cast<int>(slot - object->address()); | 3062 int offset = static_cast<int>(slot - object->address()); |
3035 return object->IsValidSlot(offset); | 3063 return object->IsValidSlot(offset); |
3036 } | 3064 } |
3037 | 3065 |
3038 | 3066 |
3039 void MarkCompactCollector::VerifyIsSlotInLiveObject(Address slot, | 3067 void MarkCompactCollector::VerifyIsSlotInLiveObject(Address slot, |
3040 HeapObject* object) { | 3068 HeapObject* object) { |
3041 // The target object has to be black. | 3069 // The target object has to be black. |
3042 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 3070 CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
3043 | 3071 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3426 // Slots in live objects pointing into evacuation candidates are updated | 3454 // Slots in live objects pointing into evacuation candidates are updated |
3427 // if requested. | 3455 // if requested. |
3428 // Returns the size of the biggest continuous freed memory chunk in bytes. | 3456 // Returns the size of the biggest continuous freed memory chunk in bytes. |
3429 template <SweepingMode sweeping_mode, | 3457 template <SweepingMode sweeping_mode, |
3430 MarkCompactCollector::SweepingParallelism parallelism, | 3458 MarkCompactCollector::SweepingParallelism parallelism, |
3431 SkipListRebuildingMode skip_list_mode, | 3459 SkipListRebuildingMode skip_list_mode, |
3432 FreeSpaceTreatmentMode free_space_mode> | 3460 FreeSpaceTreatmentMode free_space_mode> |
3433 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p, | 3461 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p, |
3434 ObjectVisitor* v) { | 3462 ObjectVisitor* v) { |
3435 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); | 3463 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); |
3464 DCHECK(!p->IsFlagSet(Page::BLACK_PAGE)); | |
3436 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, | 3465 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, |
3437 space->identity() == CODE_SPACE); | 3466 space->identity() == CODE_SPACE); |
3438 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); | 3467 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); |
3439 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || | 3468 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || |
3440 sweeping_mode == SWEEP_ONLY); | 3469 sweeping_mode == SWEEP_ONLY); |
3441 | 3470 |
3442 Address free_start = p->area_start(); | 3471 Address free_start = p->area_start(); |
3443 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3472 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
3444 | 3473 |
3445 // If we use the skip list for code space pages, we have to lock the skip | 3474 // If we use the skip list for code space pages, we have to lock the skip |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3882 | 3911 |
3883 PageIterator it(space); | 3912 PageIterator it(space); |
3884 | 3913 |
3885 int will_be_swept = 0; | 3914 int will_be_swept = 0; |
3886 bool unused_page_present = false; | 3915 bool unused_page_present = false; |
3887 | 3916 |
3888 while (it.has_next()) { | 3917 while (it.has_next()) { |
3889 Page* p = it.next(); | 3918 Page* p = it.next(); |
3890 DCHECK(p->SweepingDone()); | 3919 DCHECK(p->SweepingDone()); |
3891 | 3920 |
3921 // We can not sweep black pages, since all mark bits are set for these | |
3922 // pages. | |
3923 if (p->IsFlagSet(Page::BLACK_PAGE)) { | |
3924 Bitmap::Clear(p); | |
3925 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); | |
3926 p->ClearFlag(Page::BLACK_PAGE); | |
3927 // TODO(hpayer): Free unused memory of last black page. | |
3928 continue; | |
3929 } | |
3930 | |
3892 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) || | 3931 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) || |
3893 p->IsEvacuationCandidate()) { | 3932 p->IsEvacuationCandidate()) { |
3894 // Will be processed in EvacuateNewSpaceAndCandidates. | 3933 // Will be processed in EvacuateNewSpaceAndCandidates. |
3895 DCHECK(evacuation_candidates_.length() > 0); | 3934 DCHECK(evacuation_candidates_.length() > 0); |
3896 continue; | 3935 continue; |
3897 } | 3936 } |
3898 | 3937 |
3899 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { | 3938 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { |
3900 // We need to sweep the page to get it into an iterable state again. Note | 3939 // We need to sweep the page to get it into an iterable state again. Note |
3901 // that this adds unusable memory into the free list that is later on | 3940 // that this adds unusable memory into the free list that is later on |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4056 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4095 MarkBit mark_bit = Marking::MarkBitFrom(host); |
4057 if (Marking::IsBlack(mark_bit)) { | 4096 if (Marking::IsBlack(mark_bit)) { |
4058 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 4097 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
4059 RecordRelocSlot(&rinfo, target); | 4098 RecordRelocSlot(&rinfo, target); |
4060 } | 4099 } |
4061 } | 4100 } |
4062 } | 4101 } |
4063 | 4102 |
4064 } // namespace internal | 4103 } // namespace internal |
4065 } // namespace v8 | 4104 } // namespace v8 |
OLD | NEW |