1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_INCREMENTAL_MARKING_INL_H_ 29 #define V8_INCREMENTAL_MARKING_INL_H_ 30 31 #include "incremental-marking.h" 32 33 namespace v8 { 34 namespace internal { 35 36 37 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, 38 Object** slot, 39 Object* value) { 40 HeapObject* value_heap_obj = HeapObject::cast(value); 41 MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj); 42 if (Marking::IsWhite(value_bit)) { 43 MarkBit obj_bit = Marking::MarkBitFrom(obj); 44 if (Marking::IsBlack(obj_bit)) { 45 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); 46 if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { 47 if (chunk->IsLeftOfProgressBar(slot)) { 48 WhiteToGreyAndPush(value_heap_obj, value_bit); 49 RestartIfNotMarking(); 50 } else { 51 return false; 52 } 53 } else { 54 BlackToGreyAndUnshift(obj, obj_bit); 55 RestartIfNotMarking(); 56 return false; 57 } 58 } else { 59 return false; 60 } 61 } 62 if (!is_compacting_) return false; 63 MarkBit obj_bit = Marking::MarkBitFrom(obj); 64 return Marking::IsBlack(obj_bit); 65 } 66 67 68 void IncrementalMarking::RecordWrite(HeapObject* obj, 69 Object** slot, 70 Object* value) { 71 if (IsMarking() && value->NonFailureIsHeapObject()) { 72 RecordWriteSlow(obj, slot, value); 73 } 74 } 75 76 77 void IncrementalMarking::RecordWriteOfCodeEntry(JSFunction* host, 78 Object** slot, 79 Code* value) { 80 if (IsMarking()) RecordWriteOfCodeEntrySlow(host, slot, value); 81 } 82 83 84 void IncrementalMarking::RecordWriteIntoCode(HeapObject* obj, 85 RelocInfo* rinfo, 86 Object* value) { 87 if (IsMarking() && value->NonFailureIsHeapObject()) { 88 RecordWriteIntoCodeSlow(obj, rinfo, value); 89 } 90 } 91 92 93 void IncrementalMarking::RecordWrites(HeapObject* obj) { 94 if (IsMarking()) { 95 MarkBit obj_bit = Marking::MarkBitFrom(obj); 96 if (Marking::IsBlack(obj_bit)) { 97 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); 98 if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { 99 chunk->set_progress_bar(0); 100 } 101 BlackToGreyAndUnshift(obj, obj_bit); 102 RestartIfNotMarking(); 103 } 104 } 105 } 106 107 108 void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj, 109 MarkBit mark_bit) { 110 ASSERT(Marking::MarkBitFrom(obj) == mark_bit); 111 ASSERT(obj->Size() >= 2*kPointerSize); 112 ASSERT(IsMarking()); 113 Marking::BlackToGrey(mark_bit); 114 int obj_size = obj->Size(); 115 MemoryChunk::IncrementLiveBytesFromGC(obj->address(), -obj_size); 116 bytes_scanned_ -= obj_size; 117 int64_t old_bytes_rescanned = bytes_rescanned_; 118 bytes_rescanned_ = old_bytes_rescanned + obj_size; 119 if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) { 120 if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSizeOfObjects()) { 121 // If we have queued twice the heap size for rescanning then we are 122 // going around in circles, scanning the same objects again and again 123 // as the program mutates the heap faster than we can incrementally 124 // trace it. In this case we switch to non-incremental marking in 125 // order to finish off this marking phase. 126 if (FLAG_trace_gc) { 127 PrintPID("Hurrying incremental marking because of lack of progress\n"); 128 } 129 marking_speed_ = kMaxMarkingSpeed; 130 } 131 } 132 133 marking_deque_.UnshiftGrey(obj); 134 } 135 136 137 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { 138 Marking::WhiteToGrey(mark_bit); 139 marking_deque_.PushGrey(obj); 140 } 141 142 143 } } // namespace v8::internal 144 145 #endif // V8_INCREMENTAL_MARKING_INL_H_ 146