Home | History | Annotate | Download | only in heap
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_HEAP_INCREMENTAL_MARKING_INL_H_
      6 #define V8_HEAP_INCREMENTAL_MARKING_INL_H_
      7 
      8 #include "src/heap/incremental-marking.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 
     14 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object** slot,
     15                                          Object* value) {
     16   HeapObject* value_heap_obj = HeapObject::cast(value);
     17   MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj);
     18   if (Marking::IsWhite(value_bit)) {
     19     MarkBit obj_bit = Marking::MarkBitFrom(obj);
     20     if (Marking::IsBlack(obj_bit)) {
     21       MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
     22       if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) {
     23         if (chunk->IsLeftOfProgressBar(slot)) {
     24           WhiteToGreyAndPush(value_heap_obj, value_bit);
     25           RestartIfNotMarking();
     26         } else {
     27           return false;
     28         }
     29       } else {
     30         BlackToGreyAndUnshift(obj, obj_bit);
     31         RestartIfNotMarking();
     32         return false;
     33       }
     34     } else {
     35       return false;
     36     }
     37   }
     38   if (!is_compacting_) return false;
     39   MarkBit obj_bit = Marking::MarkBitFrom(obj);
     40   return Marking::IsBlack(obj_bit);
     41 }
     42 
     43 
     44 void IncrementalMarking::RecordWrite(HeapObject* obj, Object** slot,
     45                                      Object* value) {
     46   if (IsMarking() && value->IsHeapObject()) {
     47     RecordWriteSlow(obj, slot, value);
     48   }
     49 }
     50 
     51 
     52 void IncrementalMarking::RecordWriteOfCodeEntry(JSFunction* host, Object** slot,
     53                                                 Code* value) {
     54   if (IsMarking()) RecordWriteOfCodeEntrySlow(host, slot, value);
     55 }
     56 
     57 
     58 void IncrementalMarking::RecordWriteIntoCode(HeapObject* obj, RelocInfo* rinfo,
     59                                              Object* value) {
     60   if (IsMarking() && value->IsHeapObject()) {
     61     RecordWriteIntoCodeSlow(obj, rinfo, value);
     62   }
     63 }
     64 
     65 
     66 void IncrementalMarking::RecordWrites(HeapObject* obj) {
     67   if (IsMarking()) {
     68     MarkBit obj_bit = Marking::MarkBitFrom(obj);
     69     if (Marking::IsBlack(obj_bit)) {
     70       MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
     71       if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) {
     72         chunk->set_progress_bar(0);
     73       }
     74       BlackToGreyAndUnshift(obj, obj_bit);
     75       RestartIfNotMarking();
     76     }
     77   }
     78 }
     79 
     80 
     81 void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj,
     82                                                MarkBit mark_bit) {
     83   DCHECK(Marking::MarkBitFrom(obj) == mark_bit);
     84   DCHECK(obj->Size() >= 2 * kPointerSize);
     85   DCHECK(IsMarking());
     86   Marking::BlackToGrey(mark_bit);
     87   int obj_size = obj->Size();
     88   MemoryChunk::IncrementLiveBytesFromGC(obj->address(), -obj_size);
     89   bytes_scanned_ -= obj_size;
     90   int64_t old_bytes_rescanned = bytes_rescanned_;
     91   bytes_rescanned_ = old_bytes_rescanned + obj_size;
     92   if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) {
     93     if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSizeOfObjects()) {
     94       // If we have queued twice the heap size for rescanning then we are
     95       // going around in circles, scanning the same objects again and again
     96       // as the program mutates the heap faster than we can incrementally
     97       // trace it.  In this case we switch to non-incremental marking in
     98       // order to finish off this marking phase.
     99       if (FLAG_trace_gc) {
    100         PrintPID("Hurrying incremental marking because of lack of progress\n");
    101       }
    102       marking_speed_ = kMaxMarkingSpeed;
    103     }
    104   }
    105 
    106   marking_deque_.UnshiftGrey(obj);
    107 }
    108 
    109 
    110 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
    111   Marking::WhiteToGrey(mark_bit);
    112   marking_deque_.PushGrey(obj);
    113 }
    114 }
    115 }  // namespace v8::internal
    116 
    117 #endif  // V8_HEAP_INCREMENTAL_MARKING_INL_H_
    118