Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: src/heap/mark-compact.cc

Issue 2003553002: [heap] Introduce a new remembered set for typed pointers from old to new. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/remembered-set.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2805 matching lines...) Expand 10 before | Expand all | Expand 10 after
2816 reinterpret_cast<base::AtomicWord*>(slot), 2816 reinterpret_cast<base::AtomicWord*>(slot),
2817 reinterpret_cast<base::AtomicWord>(obj), 2817 reinterpret_cast<base::AtomicWord>(obj),
2818 reinterpret_cast<base::AtomicWord>(target)); 2818 reinterpret_cast<base::AtomicWord>(target));
2819 DCHECK(!heap_obj->GetHeap()->InFromSpace(target) && 2819 DCHECK(!heap_obj->GetHeap()->InFromSpace(target) &&
2820 !MarkCompactCollector::IsOnEvacuationCandidate(target)); 2820 !MarkCompactCollector::IsOnEvacuationCandidate(target));
2821 } 2821 }
2822 } 2822 }
2823 return REMOVE_SLOT; 2823 return REMOVE_SLOT;
2824 } 2824 }
2825 2825
2826 // Updates a cell slot using an untyped slot callback.
2827 // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
2828 template <typename Callback>
2829 static SlotCallbackResult UpdateCell(RelocInfo* rinfo, Callback callback) {
2830 DCHECK(rinfo->rmode() == RelocInfo::CELL);
2831 Object* cell = rinfo->target_cell();
2832 Object* old_cell = cell;
2833 SlotCallbackResult result = callback(&cell);
2834 if (cell != old_cell) {
2835 rinfo->set_target_cell(reinterpret_cast<Cell*>(cell));
2836 }
2837 return result;
2838 }
2839
2840 // Updates a code entry slot using an untyped slot callback.
2841 // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
2842 template <typename Callback>
2843 static SlotCallbackResult UpdateCodeEntry(Address entry_address,
2844 Callback callback) {
2845 Object* code = Code::GetObjectFromEntryAddress(entry_address);
2846 Object* old_code = code;
2847 SlotCallbackResult result = callback(&code);
2848 if (code != old_code) {
2849 Memory::Address_at(entry_address) = reinterpret_cast<Code*>(code)->entry();
2850 }
2851 return result;
2852 }
2853
2854 // Updates a code target slot using an untyped slot callback.
2855 // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
2856 template <typename Callback>
2857 static SlotCallbackResult UpdateCodeTarget(RelocInfo* rinfo,
2858 Callback callback) {
2859 DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
2860 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
2861 Object* old_target = target;
2862 SlotCallbackResult result = callback(&target);
2863 if (target != old_target) {
2864 rinfo->set_target_address(Code::cast(target)->instruction_start());
2865 }
2866 return result;
2867 }
2868
2869 // Updates an embedded pointer slot using an untyped slot callback.
2870 // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
2871 template <typename Callback>
2872 static SlotCallbackResult UpdateEmbeddedPointer(RelocInfo* rinfo,
2873 Callback callback) {
2874 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
2875 Object* target = rinfo->target_object();
2876 Object* old_target = target;
2877 SlotCallbackResult result = callback(&target);
2878 if (target != old_target) {
2879 rinfo->set_target_object(target);
2880 }
2881 return result;
2882 }
2883
2884 // Updates a debug target slot using an untyped slot callback.
2885 // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
2886 template <typename Callback>
2887 static SlotCallbackResult UpdateDebugTarget(RelocInfo* rinfo,
2888 Callback callback) {
2889 DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
2890 rinfo->IsPatchedDebugBreakSlotSequence());
2891 Object* target = Code::GetCodeFromTargetAddress(rinfo->debug_call_address());
2892 SlotCallbackResult result = callback(&target);
2893 rinfo->set_debug_call_address(Code::cast(target)->instruction_start());
2894 return result;
2895 }
2896
2897 // Updates a typed slot using an untyped slot callback.
2898 // The callback accepts (Heap*, Object**) and returns SlotCallbackResult.
2899 template <typename Callback>
2900 static SlotCallbackResult UpdateTypedSlot(Isolate* isolate, SlotType slot_type,
2901 Address addr, Callback callback) {
2902 switch (slot_type) {
2903 case CODE_TARGET_SLOT: {
2904 RelocInfo rinfo(isolate, addr, RelocInfo::CODE_TARGET, 0, NULL);
2905 return UpdateCodeTarget(&rinfo, callback);
2906 }
2907 case CELL_TARGET_SLOT: {
2908 RelocInfo rinfo(isolate, addr, RelocInfo::CELL, 0, NULL);
2909 return UpdateCell(&rinfo, callback);
2910 }
2911 case CODE_ENTRY_SLOT: {
2912 return UpdateCodeEntry(addr, callback);
2913 }
2914 case DEBUG_TARGET_SLOT: {
2915 RelocInfo rinfo(isolate, addr, RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION, 0,
2916 NULL);
2917 if (rinfo.IsPatchedDebugBreakSlotSequence()) {
2918 return UpdateDebugTarget(&rinfo, callback);
2919 }
2920 return REMOVE_SLOT;
2921 }
2922 case EMBEDDED_OBJECT_SLOT: {
2923 RelocInfo rinfo(isolate, addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL);
2924 return UpdateEmbeddedPointer(&rinfo, callback);
2925 }
2926 case OBJECT_SLOT: {
2927 return callback(reinterpret_cast<Object**>(addr));
2928 }
2929 case NUMBER_OF_SLOT_TYPES:
2930 break;
2931 }
2932 UNREACHABLE();
2933 return REMOVE_SLOT;
2934 }
2935
2936
2937 // Visitor for updating pointers from live objects in old spaces to new space. 2826 // Visitor for updating pointers from live objects in old spaces to new space.
2938 // It does not expect to encounter pointers to dead objects. 2827 // It does not expect to encounter pointers to dead objects.
2939 class PointersUpdatingVisitor : public ObjectVisitor { 2828 class PointersUpdatingVisitor : public ObjectVisitor {
2940 public: 2829 public:
2941 void VisitPointer(Object** p) override { UpdateSlot(p); } 2830 void VisitPointer(Object** p) override { UpdateSlot(p); }
2942 2831
2943 void VisitPointers(Object** start, Object** end) override { 2832 void VisitPointers(Object** start, Object** end) override {
2944 for (Object** p = start; p < end; p++) UpdateSlot(p); 2833 for (Object** p = start; p < end; p++) UpdateSlot(p);
2945 } 2834 }
2946 2835
2947 void VisitCell(RelocInfo* rinfo) override { UpdateCell(rinfo, UpdateSlot); } 2836 void VisitCell(RelocInfo* rinfo) override {
2837 UpdateTypedSlotHelper::UpdateCell(rinfo, UpdateSlot);
2838 }
2948 2839
2949 void VisitEmbeddedPointer(RelocInfo* rinfo) override { 2840 void VisitEmbeddedPointer(RelocInfo* rinfo) override {
2950 UpdateEmbeddedPointer(rinfo, UpdateSlot); 2841 UpdateTypedSlotHelper::UpdateEmbeddedPointer(rinfo, UpdateSlot);
2951 } 2842 }
2952 2843
2953 void VisitCodeTarget(RelocInfo* rinfo) override { 2844 void VisitCodeTarget(RelocInfo* rinfo) override {
2954 UpdateCodeTarget(rinfo, UpdateSlot); 2845 UpdateTypedSlotHelper::UpdateCodeTarget(rinfo, UpdateSlot);
2955 } 2846 }
2956 2847
2957 void VisitCodeEntry(Address entry_address) override { 2848 void VisitCodeEntry(Address entry_address) override {
2958 UpdateCodeEntry(entry_address, UpdateSlot); 2849 UpdateTypedSlotHelper::UpdateCodeEntry(entry_address, UpdateSlot);
2959 } 2850 }
2960 2851
2961 void VisitDebugTarget(RelocInfo* rinfo) override { 2852 void VisitDebugTarget(RelocInfo* rinfo) override {
2962 UpdateDebugTarget(rinfo, UpdateSlot); 2853 UpdateTypedSlotHelper::UpdateDebugTarget(rinfo, UpdateSlot);
2963 } 2854 }
2964 }; 2855 };
2965 2856
2966 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, 2857 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap,
2967 Object** p) { 2858 Object** p) {
2968 MapWord map_word = HeapObject::cast(*p)->map_word(); 2859 MapWord map_word = HeapObject::cast(*p)->map_word();
2969 2860
2970 if (map_word.IsForwardingAddress()) { 2861 if (map_word.IsForwardingAddress()) {
2971 return String::cast(map_word.ToForwardingAddress()); 2862 return String::cast(map_word.ToForwardingAddress());
2972 } 2863 }
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
3502 MarkBit mark_bit = Marking::MarkBitFrom(code); 3393 MarkBit mark_bit = Marking::MarkBitFrom(code);
3503 if (Marking::IsWhite(mark_bit)) return; 3394 if (Marking::IsWhite(mark_bit)) return;
3504 3395
3505 // Ignore all slots that might have been recorded in the body of the 3396 // Ignore all slots that might have been recorded in the body of the
3506 // deoptimized code object. Assumption: no slots will be recorded for 3397 // deoptimized code object. Assumption: no slots will be recorded for
3507 // this object after invalidating it. 3398 // this object after invalidating it.
3508 Page* page = Page::FromAddress(code->address()); 3399 Page* page = Page::FromAddress(code->address());
3509 Address start = code->instruction_start(); 3400 Address start = code->instruction_start();
3510 Address end = code->address() + code->Size(); 3401 Address end = code->address() + code->Size();
3511 RememberedSet<OLD_TO_OLD>::RemoveRangeTyped(page, start, end); 3402 RememberedSet<OLD_TO_OLD>::RemoveRangeTyped(page, start, end);
3403 RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(page, start, end);
3512 } 3404 }
3513 } 3405 }
3514 3406
3515 3407
3516 // Return true if the given code is deoptimized or will be deoptimized. 3408 // Return true if the given code is deoptimized or will be deoptimized.
3517 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { 3409 bool MarkCompactCollector::WillBeDeoptimized(Code* code) {
3518 return code->is_optimized_code() && code->marked_for_deoptimization(); 3410 return code->is_optimized_code() && code->marked_for_deoptimization();
3519 } 3411 }
3520 3412
3521 3413
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
3674 return UpdateSlot(reinterpret_cast<Object**>(slot)); 3566 return UpdateSlot(reinterpret_cast<Object**>(slot));
3675 }); 3567 });
3676 } 3568 }
3677 } 3569 }
3678 3570
3679 static void UpdateTypedPointers(Heap* heap, MemoryChunk* chunk) { 3571 static void UpdateTypedPointers(Heap* heap, MemoryChunk* chunk) {
3680 if (direction == OLD_TO_OLD) { 3572 if (direction == OLD_TO_OLD) {
3681 Isolate* isolate = heap->isolate(); 3573 Isolate* isolate = heap->isolate();
3682 RememberedSet<OLD_TO_OLD>::IterateTyped( 3574 RememberedSet<OLD_TO_OLD>::IterateTyped(
3683 chunk, [isolate](SlotType type, Address slot) { 3575 chunk, [isolate](SlotType type, Address slot) {
3684 return UpdateTypedSlot(isolate, type, slot, UpdateSlot); 3576 return UpdateTypedSlotHelper::UpdateTypedSlot(isolate, type, slot,
3577 UpdateSlot);
3578 });
3579 } else {
3580 Isolate* isolate = heap->isolate();
3581 RememberedSet<OLD_TO_NEW>::IterateTyped(
3582 chunk, [isolate, heap](SlotType type, Address slot) {
3583 return UpdateTypedSlotHelper::UpdateTypedSlot(
3584 isolate, type, slot, [heap](Object** slot) {
3585 return CheckAndUpdateOldToNewSlot(
ulan 2016/05/23 08:40:08 For separate CL: We would need to force promotion
3586 heap, reinterpret_cast<Address>(slot));
3587 });
3685 }); 3588 });
3686 } 3589 }
3687 } 3590 }
3688 3591
3689 static SlotCallbackResult CheckAndUpdateOldToNewSlot(Heap* heap, 3592 static SlotCallbackResult CheckAndUpdateOldToNewSlot(Heap* heap,
3690 Address slot_address) { 3593 Address slot_address) {
3691 Object** slot = reinterpret_cast<Object**>(slot_address); 3594 Object** slot = reinterpret_cast<Object**>(slot_address);
3692 if (heap->InFromSpace(*slot)) { 3595 if (heap->InFromSpace(*slot)) {
3693 HeapObject* heap_object = reinterpret_cast<HeapObject*>(*slot); 3596 HeapObject* heap_object = reinterpret_cast<HeapObject*>(*slot);
3694 DCHECK(heap_object->IsHeapObject()); 3597 DCHECK(heap_object->IsHeapObject());
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
4033 MarkBit mark_bit = Marking::MarkBitFrom(host); 3936 MarkBit mark_bit = Marking::MarkBitFrom(host);
4034 if (Marking::IsBlack(mark_bit)) { 3937 if (Marking::IsBlack(mark_bit)) {
4035 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 3938 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
4036 RecordRelocSlot(host, &rinfo, target); 3939 RecordRelocSlot(host, &rinfo, target);
4037 } 3940 }
4038 } 3941 }
4039 } 3942 }
4040 3943
4041 } // namespace internal 3944 } // namespace internal
4042 } // namespace v8 3945 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/remembered-set.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698