Home | History | Annotate | Download | only in src
      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