13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
23ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Redistribution and use in source and binary forms, with or without
33ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// modification, are permitted provided that the following conditions are
43ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// met:
53ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
63ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions of source code must retain the above copyright
73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       notice, this list of conditions and the following disclaimer.
83ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions in binary form must reproduce the above
93ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       copyright notice, this list of conditions and the following
103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       disclaimer in the documentation and/or other materials provided
113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       with the distribution.
123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Neither the name of Google Inc. nor the names of its
133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       contributors may be used to endorse or promote products derived
143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       from this software without specific prior written permission.
153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifndef V8_INCREMENTAL_MARKING_INL_H_
293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define V8_INCREMENTAL_MARKING_INL_H_
303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "incremental-marking.h"
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnamespace v8 {
343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnamespace internal {
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool IncrementalMarking::BaseRecordWrite(HeapObject* obj,
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Object** slot,
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Object* value) {
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MarkBit value_bit = Marking::MarkBitFrom(HeapObject::cast(value));
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (Marking::IsWhite(value_bit)) {
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkBit obj_bit = Marking::MarkBitFrom(obj);
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (Marking::IsBlack(obj_bit)) {
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      BlackToGreyAndUnshift(obj, obj_bit);
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RestartIfNotMarking();
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Object is either grey or white.  It will be scanned if survives.
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return false;
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return true;
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordWrite(HeapObject* obj,
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Object** slot,
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Object* value) {
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsMarking() && value->NonFailureIsHeapObject()) {
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RecordWriteSlow(obj, slot, value);
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordWriteOfCodeEntry(JSFunction* host,
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                Object** slot,
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                Code* value) {
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsMarking()) RecordWriteOfCodeEntrySlow(host, slot, value);
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordWriteIntoCode(HeapObject* obj,
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             RelocInfo* rinfo,
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             Object* value) {
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsMarking() && value->NonFailureIsHeapObject()) {
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RecordWriteIntoCodeSlow(obj, rinfo, value);
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordWrites(HeapObject* obj) {
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsMarking()) {
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkBit obj_bit = Marking::MarkBitFrom(obj);
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (Marking::IsBlack(obj_bit)) {
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      BlackToGreyAndUnshift(obj, obj_bit);
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RestartIfNotMarking();
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj,
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               MarkBit mark_bit) {
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(Marking::MarkBitFrom(obj) == mark_bit);
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(obj->Size() >= 2*kPointerSize);
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IsMarking());
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Marking::BlackToGrey(mark_bit);
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int obj_size = obj->Size();
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MemoryChunk::IncrementLiveBytesFromGC(obj->address(), -obj_size);
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bytes_scanned_ -= obj_size;
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int64_t old_bytes_rescanned = bytes_rescanned_;
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bytes_rescanned_ = old_bytes_rescanned + obj_size;
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) {
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSize()) {
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // If we have queued twice the heap size for rescanning then we are
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // going around in circles, scanning the same objects again and again
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // as the program mutates the heap faster than we can incrementally
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // trace it.  In this case we switch to non-incremental marking in
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // order to finish off this marking phase.
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (FLAG_trace_gc) {
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        PrintF("Hurrying incremental marking because of lack of progress\n");
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      allocation_marking_factor_ = kMaxAllocationMarkingFactor;
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  marking_deque_.UnshiftGrey(obj);
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  WhiteToGrey(obj, mark_bit);
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  marking_deque_.PushGrey(obj);
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::WhiteToGrey(HeapObject* obj, MarkBit mark_bit) {
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Marking::WhiteToGrey(mark_bit);
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} }  // namespace v8::internal
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif  // V8_INCREMENTAL_MARKING_INL_H_
134