Home | History | Annotate | Download | only in src
      1 // Copyright 2011 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   MarkBit value_bit = Marking::MarkBitFrom(HeapObject::cast(value));
     41   if (Marking::IsWhite(value_bit)) {
     42     MarkBit obj_bit = Marking::MarkBitFrom(obj);
     43     if (Marking::IsBlack(obj_bit)) {
     44       BlackToGreyAndUnshift(obj, obj_bit);
     45       RestartIfNotMarking();
     46     }
     47 
     48     // Object is either grey or white.  It will be scanned if survives.
     49     return false;
     50   }
     51   return true;
     52 }
     53 
     54 
     55 void IncrementalMarking::RecordWrite(HeapObject* obj,
     56                                      Object** slot,
     57                                      Object* value) {
     58   if (IsMarking() && value->NonFailureIsHeapObject()) {
     59     RecordWriteSlow(obj, slot, value);
     60   }
     61 }
     62 
     63 
     64 void IncrementalMarking::RecordWriteOfCodeEntry(JSFunction* host,
     65                                                 Object** slot,
     66                                                 Code* value) {
     67   if (IsMarking()) RecordWriteOfCodeEntrySlow(host, slot, value);
     68 }
     69 
     70 
     71 void IncrementalMarking::RecordWriteIntoCode(HeapObject* obj,
     72                                              RelocInfo* rinfo,
     73                                              Object* value) {
     74   if (IsMarking() && value->NonFailureIsHeapObject()) {
     75     RecordWriteIntoCodeSlow(obj, rinfo, value);
     76   }
     77 }
     78 
     79 
     80 void IncrementalMarking::RecordWrites(HeapObject* obj) {
     81   if (IsMarking()) {
     82     MarkBit obj_bit = Marking::MarkBitFrom(obj);
     83     if (Marking::IsBlack(obj_bit)) {
     84       BlackToGreyAndUnshift(obj, obj_bit);
     85       RestartIfNotMarking();
     86     }
     87   }
     88 }
     89 
     90 
     91 void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj,
     92                                                MarkBit mark_bit) {
     93   ASSERT(Marking::MarkBitFrom(obj) == mark_bit);
     94   ASSERT(obj->Size() >= 2*kPointerSize);
     95   ASSERT(IsMarking());
     96   Marking::BlackToGrey(mark_bit);
     97   int obj_size = obj->Size();
     98   MemoryChunk::IncrementLiveBytesFromGC(obj->address(), -obj_size);
     99   bytes_scanned_ -= obj_size;
    100   int64_t old_bytes_rescanned = bytes_rescanned_;
    101   bytes_rescanned_ = old_bytes_rescanned + obj_size;
    102   if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) {
    103     if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSize()) {
    104       // If we have queued twice the heap size for rescanning then we are
    105       // going around in circles, scanning the same objects again and again
    106       // as the program mutates the heap faster than we can incrementally
    107       // trace it.  In this case we switch to non-incremental marking in
    108       // order to finish off this marking phase.
    109       if (FLAG_trace_gc) {
    110         PrintF("Hurrying incremental marking because of lack of progress\n");
    111       }
    112       allocation_marking_factor_ = kMaxAllocationMarkingFactor;
    113     }
    114   }
    115 
    116   marking_deque_.UnshiftGrey(obj);
    117 }
    118 
    119 
    120 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
    121   WhiteToGrey(obj, mark_bit);
    122   marking_deque_.PushGrey(obj);
    123 }
    124 
    125 
    126 void IncrementalMarking::WhiteToGrey(HeapObject* obj, MarkBit mark_bit) {
    127   Marking::WhiteToGrey(mark_bit);
    128 }
    129 
    130 
    131 } }  // namespace v8::internal
    132 
    133 #endif  // V8_INCREMENTAL_MARKING_INL_H_
    134