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