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#include "v8.h"
293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "incremental-marking.h"
313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "code-stubs.h"
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "compilation-cache.h"
343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "v8conversions.h"
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnamespace v8 {
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnamespace internal {
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochIncrementalMarking::IncrementalMarking(Heap* heap)
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : heap_(heap),
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      state_(STOPPED),
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      marking_deque_memory_(NULL),
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      marking_deque_memory_committed_(false),
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      steps_count_(0),
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      steps_took_(0),
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      longest_step_(0.0),
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      old_generation_space_available_at_start_of_incremental_(0),
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      old_generation_space_used_at_start_of_incremental_(0),
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      steps_count_since_last_gc_(0),
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      steps_took_since_last_gc_(0),
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      should_hurry_(false),
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      allocation_marking_factor_(0),
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      allocated_(0),
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      no_marking_scope_depth_(0) {
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::TearDown() {
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  delete marking_deque_memory_;
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordWriteSlow(HeapObject* obj,
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Object** slot,
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Object* value) {
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (BaseRecordWrite(obj, slot, value) && is_compacting_ && slot != NULL) {
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkBit obj_bit = Marking::MarkBitFrom(obj);
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (Marking::IsBlack(obj_bit)) {
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // Object is not going to be rescanned we need to record the slot.
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap_->mark_compact_collector()->RecordSlot(
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          HeapObject::RawField(obj, 0), slot, value);
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordWriteFromCode(HeapObject* obj,
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             Object* value,
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             Isolate* isolate) {
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(obj->IsHeapObject());
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Fast cases should already be covered by RecordWriteStub.
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(value->IsHeapObject());
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(!value->IsHeapNumber());
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(!value->IsString() ||
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         value->IsConsString() ||
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         value->IsSlicedString());
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(value))));
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IncrementalMarking* marking = isolate->heap()->incremental_marking();
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(!marking->is_compacting_);
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  marking->RecordWrite(obj, NULL, value);
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordWriteForEvacuationFromCode(HeapObject* obj,
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                          Object** slot,
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                          Isolate* isolate) {
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IncrementalMarking* marking = isolate->heap()->incremental_marking();
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(marking->is_compacting_);
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  marking->RecordWrite(obj, slot, *slot);
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordCodeTargetPatch(Code* host,
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Address pc,
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               HeapObject* value) {
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsMarking()) {
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host);
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RecordWriteIntoCode(host, &rinfo, value);
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordCodeTargetPatch(Address pc, HeapObject* value) {
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsMarking()) {
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Code* host = heap_->isolate()->inner_pointer_to_code_cache()->
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        GcSafeFindCodeForInnerPointer(pc);
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host);
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RecordWriteIntoCode(host, &rinfo, value);
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordWriteOfCodeEntrySlow(JSFunction* host,
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                Object** slot,
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                Code* value) {
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (BaseRecordWrite(host, slot, value) && is_compacting_) {
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(slot != NULL);
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    heap_->mark_compact_collector()->
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        RecordCodeEntrySlot(reinterpret_cast<Address>(slot), value);
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::RecordWriteIntoCodeSlow(HeapObject* obj,
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                 RelocInfo* rinfo,
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                 Object* value) {
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MarkBit value_bit = Marking::MarkBitFrom(HeapObject::cast(value));
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (Marking::IsWhite(value_bit)) {
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkBit obj_bit = Marking::MarkBitFrom(obj);
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (Marking::IsBlack(obj_bit)) {
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      BlackToGreyAndUnshift(obj, obj_bit);
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RestartIfNotMarking();
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Object is either grey or white.  It will be scanned if survives.
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return;
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (is_compacting_) {
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkBit obj_bit = Marking::MarkBitFrom(obj);
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (Marking::IsBlack(obj_bit)) {
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // Object is not going to be rescanned.  We need to record the slot.
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap_->mark_compact_collector()->RecordRelocSlot(rinfo,
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                       Code::cast(value));
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass IncrementalMarkingMarkingVisitor : public ObjectVisitor {
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IncrementalMarkingMarkingVisitor(Heap* heap,
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   IncrementalMarking* incremental_marking)
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : heap_(heap),
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        incremental_marking_(incremental_marking) {
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void VisitEmbeddedPointer(RelocInfo* rinfo) {
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target = rinfo->target_object();
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (target->NonFailureIsHeapObject()) {
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap_->mark_compact_collector()->RecordRelocSlot(rinfo, target);
1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MarkObject(target);
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void VisitCodeTarget(RelocInfo* rinfo) {
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        && (target->ic_age() != heap_->global_ic_age())) {
1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      IC::Clear(rinfo->pc());
1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkObject(target);
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void VisitDebugTarget(RelocInfo* rinfo) {
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            rinfo->IsPatchedReturnSequence()) ||
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch           (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            rinfo->IsPatchedDebugBreakSlotSequence()));
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkObject(target);
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void VisitCodeEntry(Address entry_address) {
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target = Code::GetObjectFromEntryAddress(entry_address);
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    heap_->mark_compact_collector()->
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        RecordCodeEntrySlot(entry_address, Code::cast(target));
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkObject(target);
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2088f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {
2098f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch    if (shared->ic_age() != heap_->global_ic_age()) {
2108f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch      shared->ResetForNewContext(heap_->global_ic_age());
2118f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch    }
2128f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  }
2138f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch
2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void VisitPointer(Object** p) {
2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* obj = *p;
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (obj->NonFailureIsHeapObject()) {
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap_->mark_compact_collector()->RecordSlot(p, p, obj);
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MarkObject(obj);
2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void VisitPointers(Object** start, Object** end) {
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (Object** p = start; p < end; p++) {
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Object* obj = *p;
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (obj->NonFailureIsHeapObject()) {
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        heap_->mark_compact_collector()->RecordSlot(start, p, obj);
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        MarkObject(obj);
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Mark object pointed to by p.
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  INLINE(void MarkObject(Object* obj)) {
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HeapObject* heap_object = HeapObject::cast(obj);
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (mark_bit.data_only()) {
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (incremental_marking_->MarkBlackOrKeepGrey(mark_bit)) {
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        MemoryChunk::IncrementLiveBytesFromGC(heap_object->address(),
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              heap_object->Size());
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else if (Marking::IsWhite(mark_bit)) {
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit);
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Heap* heap_;
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IncrementalMarking* incremental_marking_;
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass IncrementalMarkingRootMarkingVisitor : public ObjectVisitor {
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IncrementalMarkingRootMarkingVisitor(Heap* heap,
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       IncrementalMarking* incremental_marking)
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : heap_(heap),
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        incremental_marking_(incremental_marking) {
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void VisitPointer(Object** p) {
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkObjectByPointer(p);
2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void VisitPointers(Object** start, Object** end) {
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void MarkObjectByPointer(Object** p) {
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* obj = *p;
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!obj->IsHeapObject()) return;
2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HeapObject* heap_object = HeapObject::cast(obj);
2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (mark_bit.data_only()) {
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (incremental_marking_->MarkBlackOrKeepGrey(mark_bit)) {
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          MemoryChunk::IncrementLiveBytesFromGC(heap_object->address(),
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                heap_object->Size());
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (Marking::IsWhite(mark_bit)) {
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit);
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Heap* heap_;
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IncrementalMarking* incremental_marking_;
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk,
2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              bool is_marking,
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              bool is_compacting) {
2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (is_marking) {
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // It's difficult to filter out slots recorded for large objects.
3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (chunk->owner()->identity() == LO_SPACE &&
3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        chunk->size() > static_cast<size_t>(Page::kPageSize) &&
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        is_compacting) {
3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      chunk->SetFlag(MemoryChunk::RESCAN_ON_EVACUATION);
3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (chunk->owner()->identity() == CELL_SPACE ||
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch             chunk->scan_on_scavenge()) {
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::SetNewSpacePageFlags(NewSpacePage* chunk,
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              bool is_marking) {
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (is_marking) {
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    chunk->ClearFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  chunk->SetFlag(MemoryChunk::SCAN_ON_SCAVENGE);
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace(
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PagedSpace* space) {
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PageIterator it(space);
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (it.has_next()) {
3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Page* p = it.next();
3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetOldSpacePageFlags(p, false, false);
3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace(
3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    NewSpace* space) {
3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  NewSpacePageIterator it(space);
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (it.has_next()) {
3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    NewSpacePage* p = it.next();
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetNewSpacePageFlags(p, false);
3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::DeactivateIncrementalWriteBarrier() {
3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DeactivateIncrementalWriteBarrierForSpace(heap_->old_pointer_space());
3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DeactivateIncrementalWriteBarrierForSpace(heap_->old_data_space());
3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DeactivateIncrementalWriteBarrierForSpace(heap_->cell_space());
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DeactivateIncrementalWriteBarrierForSpace(heap_->map_space());
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DeactivateIncrementalWriteBarrierForSpace(heap_->code_space());
3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DeactivateIncrementalWriteBarrierForSpace(heap_->new_space());
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LargePage* lop = heap_->lo_space()->first_page();
3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (lop->is_valid()) {
3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetOldSpacePageFlags(lop, false, false);
3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    lop = lop->next_page();
3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::ActivateIncrementalWriteBarrier(PagedSpace* space) {
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PageIterator it(space);
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (it.has_next()) {
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Page* p = it.next();
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetOldSpacePageFlags(p, true, is_compacting_);
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::ActivateIncrementalWriteBarrier(NewSpace* space) {
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd());
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (it.has_next()) {
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    NewSpacePage* p = it.next();
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetNewSpacePageFlags(p, true);
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::ActivateIncrementalWriteBarrier() {
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ActivateIncrementalWriteBarrier(heap_->old_pointer_space());
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ActivateIncrementalWriteBarrier(heap_->old_data_space());
3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ActivateIncrementalWriteBarrier(heap_->cell_space());
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ActivateIncrementalWriteBarrier(heap_->map_space());
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ActivateIncrementalWriteBarrier(heap_->code_space());
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ActivateIncrementalWriteBarrier(heap_->new_space());
3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LargePage* lop = heap_->lo_space()->first_page();
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (lop->is_valid()) {
3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetOldSpacePageFlags(lop, true, is_compacting_);
3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    lop = lop->next_page();
3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool IncrementalMarking::WorthActivating() {
3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifndef DEBUG
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const intptr_t kActivationThreshold = 8 * MB;
4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#else
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // TODO(gc) consider setting this to some low level so that some
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // debug tests run with incremental marking and some without.
4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const intptr_t kActivationThreshold = 0;
4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return !FLAG_expose_gc &&
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FLAG_incremental_marking &&
4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      !Serializer::enabled() &&
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap_->PromotedSpaceSizeOfObjects() > kActivationThreshold;
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::ActivateGeneratedStub(Code* stub) {
4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(RecordWriteStub::GetMode(stub) ==
4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         RecordWriteStub::STORE_BUFFER_ONLY);
4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IsMarking()) {
4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Initially stub is generated in STORE_BUFFER_ONLY mode thus
4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // we don't need to do anything if incremental marking is
4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // not active.
4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (IsCompacting()) {
4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RecordWriteStub::Patch(stub, RecordWriteStub::INCREMENTAL_COMPACTION);
4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RecordWriteStub::Patch(stub, RecordWriteStub::INCREMENTAL);
4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void PatchIncrementalMarkingRecordWriteStubs(
4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Heap* heap, RecordWriteStub::Mode mode) {
4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  UnseededNumberDictionary* stubs = heap->code_stubs();
4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int capacity = stubs->Capacity();
4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < capacity; i++) {
4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* k = stubs->KeyAt(i);
4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (stubs->IsKey(k)) {
4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      uint32_t key = NumberToUint32(k);
4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (CodeStub::MajorKeyFromKey(key) ==
4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          CodeStub::RecordWrite) {
4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Object* e = stubs->ValueAt(i);
4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (e->IsCode()) {
4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          RecordWriteStub::Patch(Code::cast(e), mode);
4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::EnsureMarkingDequeIsCommitted() {
4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (marking_deque_memory_ == NULL) {
4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    marking_deque_memory_ = new VirtualMemory(4 * MB);
4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!marking_deque_memory_committed_) {
4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bool success = marking_deque_memory_->Commit(
4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        reinterpret_cast<Address>(marking_deque_memory_->address()),
4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        marking_deque_memory_->size(),
4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        false);  // Not executable.
4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK(success);
4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    marking_deque_memory_committed_ = true;
4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::UncommitMarkingDeque() {
4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (state_ == STOPPED && marking_deque_memory_committed_) {
4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bool success = marking_deque_memory_->Uncommit(
4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        reinterpret_cast<Address>(marking_deque_memory_->address()),
4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        marking_deque_memory_->size());
4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CHECK(success);
4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    marking_deque_memory_committed_ = false;
4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::Start() {
4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_trace_incremental_marking) {
4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PrintF("[IncrementalMarking] Start\n");
4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(FLAG_incremental_marking);
4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(state_ == STOPPED);
4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ResetStepCounters();
4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (heap_->old_pointer_space()->IsSweepingComplete() &&
4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap_->old_data_space()->IsSweepingComplete()) {
4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    StartMarking(ALLOW_COMPACTION);
4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FLAG_trace_incremental_marking) {
4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PrintF("[IncrementalMarking] Start sweeping.\n");
4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    state_ = SWEEPING;
4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap_->new_space()->LowerInlineAllocationLimit(kAllocatedThreshold);
4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void MarkObjectGreyDoNotEnqueue(Object* obj) {
5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (obj->IsHeapObject()) {
5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HeapObject* heap_obj = HeapObject::cast(obj);
5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkBit mark_bit = Marking::MarkBitFrom(HeapObject::cast(obj));
5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (Marking::IsBlack(mark_bit)) {
5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MemoryChunk::IncrementLiveBytesFromGC(heap_obj->address(),
5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            -heap_obj->Size());
5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Marking::AnyToGrey(mark_bit);
5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::StartMarking(CompactionFlag flag) {
5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_trace_incremental_marking) {
5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PrintF("[IncrementalMarking] Start marking\n");
5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  is_compacting_ = !FLAG_never_compact && (flag == ALLOW_COMPACTION) &&
5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap_->mark_compact_collector()->StartCompaction(
5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          MarkCompactCollector::INCREMENTAL_COMPACTION);
5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  state_ = MARKING;
5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  RecordWriteStub::Mode mode = is_compacting_ ?
5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RecordWriteStub::INCREMENTAL_COMPACTION : RecordWriteStub::INCREMENTAL;
5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PatchIncrementalMarkingRecordWriteStubs(heap_, mode);
5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  EnsureMarkingDequeIsCommitted();
5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Initialize marking stack.
5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Address addr = static_cast<Address>(marking_deque_memory_->address());
5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  size_t size = marking_deque_memory_->size();
5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_force_marking_deque_overflows) size = 64 * kPointerSize;
5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  marking_deque_.Initialize(addr, addr + size);
5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ActivateIncrementalWriteBarrier();
5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Marking bits are cleared by the sweeper.
5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_verify_heap) {
5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    heap_->mark_compact_collector()->VerifyMarkbitsAreClean();
5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap_->CompletelyClearInstanceofCache();
5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap_->isolate()->compilation_cache()->MarkCompactPrologue();
5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_cleanup_code_caches_at_gc) {
5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // We will mark cache black with a separate pass
5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // when we finish marking.
5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MarkObjectGreyDoNotEnqueue(heap_->polymorphic_code_cache());
5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Mark strong roots grey.
5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IncrementalMarkingRootMarkingVisitor visitor(heap_, this);
5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Ready to start incremental marking.
5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_trace_incremental_marking) {
5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PrintF("[IncrementalMarking] Running\n");
5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::PrepareForScavenge() {
5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IsMarking()) return;
5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  NewSpacePageIterator it(heap_->new_space()->FromSpaceStart(),
5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          heap_->new_space()->FromSpaceEnd());
5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (it.has_next()) {
5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Bitmap::Clear(it.next());
5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IsMarking()) return;
5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int current = marking_deque_.bottom();
5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int mask = marking_deque_.mask();
5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int limit = marking_deque_.top();
5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HeapObject** array = marking_deque_.array();
5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int new_top = current;
5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Map* filler_map = heap_->one_pointer_filler_map();
5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (current != limit) {
5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HeapObject* obj = array[current];
5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(obj->IsHeapObject());
5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    current = ((current + 1) & mask);
5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (heap_->InNewSpace(obj)) {
5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MapWord map_word = obj->map_word();
5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (map_word.IsForwardingAddress()) {
5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        HeapObject* dest = map_word.ToForwardingAddress();
5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        array[new_top] = dest;
5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        new_top = ((new_top + 1) & mask);
5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ASSERT(new_top != marking_deque_.bottom());
5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        MarkBit mark_bit = Marking::MarkBitFrom(obj);
6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ASSERT(Marking::IsGrey(mark_bit) ||
6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               (obj->IsFiller() && Marking::IsWhite(mark_bit)));
6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else if (obj->map() != filler_map) {
6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // Skip one word filler objects that appear on the
6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // stack when we perform in place array shift.
6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      array[new_top] = obj;
6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      new_top = ((new_top + 1) & mask);
6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ASSERT(new_top != marking_deque_.bottom());
6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG
6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        MarkBit mark_bit = Marking::MarkBitFrom(obj);
6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ASSERT(Marking::IsGrey(mark_bit) ||
6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               (obj->IsFiller() && Marking::IsWhite(mark_bit)));
6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  marking_deque_.set_top(new_top);
6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  steps_took_since_last_gc_ = 0;
6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  steps_count_since_last_gc_ = 0;
6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  longest_step_ = 0.0;
6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::VisitGlobalContext(Context* ctx, ObjectVisitor* v) {
6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  v->VisitPointers(
6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      HeapObject::RawField(
6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          ctx, Context::MarkCompactBodyDescriptor::kStartOffset),
6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      HeapObject::RawField(
6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          ctx, Context::MarkCompactBodyDescriptor::kEndOffset));
6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MarkCompactCollector* collector = heap_->mark_compact_collector();
6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int idx = Context::FIRST_WEAK_SLOT;
6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       idx < Context::GLOBAL_CONTEXT_SLOTS;
6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       ++idx) {
6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object** slot =
6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        HeapObject::RawField(ctx, FixedArray::OffsetOfElementAt(idx));
6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    collector->RecordSlot(slot, slot, *slot);
6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::Hurry() {
6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (state() == MARKING) {
6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    double start = 0.0;
6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FLAG_trace_incremental_marking) {
6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PrintF("[IncrementalMarking] Hurry\n");
6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      start = OS::TimeCurrentMillis();
6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // TODO(gc) hurry can mark objects it encounters black as mutator
6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // was stopped.
6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Map* filler_map = heap_->one_pointer_filler_map();
6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Map* global_context_map = heap_->global_context_map();
6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    while (!marking_deque_.IsEmpty()) {
6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      HeapObject* obj = marking_deque_.Pop();
6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // Explicitly skip one word fillers. Incremental markbit patterns are
6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // correct only for objects that occupy at least two words.
6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Map* map = obj->map();
6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (map == filler_map) {
6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        continue;
6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else if (map == global_context_map) {
6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // Global contexts have weak fields.
6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        VisitGlobalContext(Context::cast(obj), &marking_visitor);
6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else {
6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        obj->Iterate(&marking_visitor);
6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MarkBit mark_bit = Marking::MarkBitFrom(obj);
6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ASSERT(!Marking::IsBlack(mark_bit));
6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Marking::MarkBlack(mark_bit);
6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MemoryChunk::IncrementLiveBytesFromGC(obj->address(), obj->Size());
6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    state_ = COMPLETE;
6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FLAG_trace_incremental_marking) {
6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      double end = OS::TimeCurrentMillis();
6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PrintF("[IncrementalMarking] Complete (hurry), spent %d ms.\n",
6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch             static_cast<int>(end - start));
6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_cleanup_code_caches_at_gc) {
6843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PolymorphicCodeCache* poly_cache = heap_->polymorphic_code_cache();
6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Marking::GreyToBlack(Marking::MarkBitFrom(poly_cache));
6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MemoryChunk::IncrementLiveBytesFromGC(poly_cache->address(),
6873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          PolymorphicCodeCache::kSize);
6883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* context = heap_->global_contexts_list();
6913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (!context->IsUndefined()) {
6923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // GC can happen when the context is not fully initialized,
6933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // so the cache can be undefined.
6943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HeapObject* cache = HeapObject::cast(
6953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX));
6963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!cache->IsUndefined()) {
6973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MarkBit mark_bit = Marking::MarkBitFrom(cache);
6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (Marking::IsGrey(mark_bit)) {
6993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Marking::GreyToBlack(mark_bit);
7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        MemoryChunk::IncrementLiveBytesFromGC(cache->address(), cache->Size());
7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
7043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::Abort() {
7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsStopped()) return;
7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_trace_incremental_marking) {
7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PrintF("[IncrementalMarking] Aborting.\n");
7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap_->new_space()->LowerInlineAllocationLimit(0);
7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IncrementalMarking::set_should_hurry(false);
7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ResetStepCounters();
7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IsMarking()) {
7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PatchIncrementalMarkingRecordWriteStubs(heap_,
7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            RecordWriteStub::STORE_BUFFER_ONLY);
7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    DeactivateIncrementalWriteBarrier();
7203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (is_compacting_) {
7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      LargeObjectIterator it(heap_->lo_space());
7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
7243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Page* p = Page::FromAddress(obj->address());
7253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          p->ClearFlag(Page::RESCAN_ON_EVACUATION);
7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
7283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap_->isolate()->stack_guard()->Continue(GC_REQUEST);
7323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  state_ = STOPPED;
7333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  is_compacting_ = false;
7343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::Finalize() {
7383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Hurry();
7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  state_ = STOPPED;
7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  is_compacting_ = false;
7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap_->new_space()->LowerInlineAllocationLimit(0);
7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IncrementalMarking::set_should_hurry(false);
7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ResetStepCounters();
7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PatchIncrementalMarkingRecordWriteStubs(heap_,
7453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          RecordWriteStub::STORE_BUFFER_ONLY);
7463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DeactivateIncrementalWriteBarrier();
7473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(marking_deque_.IsEmpty());
7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap_->isolate()->stack_guard()->Continue(GC_REQUEST);
7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7528f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdochvoid IncrementalMarking::MarkingComplete(CompletionAction action) {
7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  state_ = COMPLETE;
7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // We will set the stack guard to request a GC now.  This will mean the rest
7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // of the GC gets performed as soon as possible (we can't do a GC here in a
7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // record-write context).  If a few things get allocated between now and then
7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // that shouldn't make us do a scavenge and keep being incremental, so we set
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the should-hurry flag to indicate that there can't be much work left to do.
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  set_should_hurry(true);
7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_trace_incremental_marking) {
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PrintF("[IncrementalMarking] Complete (normal).\n");
7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7638f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch  if (action == GC_VIA_STACK_GUARD) {
7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    heap_->isolate()->stack_guard()->RequestGC();
7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7698f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdochvoid IncrementalMarking::Step(intptr_t allocated_bytes,
7708f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch                              CompletionAction action) {
7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (heap_->gc_state() != Heap::NOT_IN_GC ||
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      !FLAG_incremental_marking ||
7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      !FLAG_incremental_marking_steps ||
7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (state_ != SWEEPING && state_ != MARKING)) {
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return;
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  allocated_ += allocated_bytes;
7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (allocated_ < kAllocatedThreshold) return;
7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (state_ == MARKING && no_marking_scope_depth_ > 0) return;
7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  intptr_t bytes_to_process = allocated_ * allocation_marking_factor_;
7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bytes_scanned_ += bytes_to_process;
7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  double start = 0;
7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_trace_incremental_marking || FLAG_trace_gc) {
7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    start = OS::TimeCurrentMillis();
7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (state_ == SWEEPING) {
7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (heap_->AdvanceSweepers(static_cast<int>(bytes_to_process))) {
7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bytes_scanned_ = 0;
7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      StartMarking(PREVENT_COMPACTION);
7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (state_ == MARKING) {
7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Map* filler_map = heap_->one_pointer_filler_map();
8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Map* global_context_map = heap_->global_context_map();
8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    while (!marking_deque_.IsEmpty() && bytes_to_process > 0) {
8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      HeapObject* obj = marking_deque_.Pop();
8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // Explicitly skip one word fillers. Incremental markbit patterns are
8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // correct only for objects that occupy at least two words.
8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Map* map = obj->map();
8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (map == filler_map) continue;
8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (obj->IsMap()) {
8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Map* map = Map::cast(obj);
8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        heap_->ClearCacheOnMap(map);
8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int size = obj->SizeFromMap(map);
8173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      bytes_to_process -= size;
8183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MarkBit map_mark_bit = Marking::MarkBitFrom(map);
8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (Marking::IsWhite(map_mark_bit)) {
8203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        WhiteToGreyAndPush(map, map_mark_bit);
8213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
8223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      // TODO(gc) switch to static visitor instead of normal visitor.
8243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (map == global_context_map) {
8253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // Global contexts have weak fields.
8263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Context* ctx = Context::cast(obj);
8273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // We will mark cache black with a separate pass
8293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // when we finish marking.
8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        MarkObjectGreyDoNotEnqueue(ctx->normalized_map_cache());
8313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        VisitGlobalContext(ctx, &marking_visitor);
8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else {
8343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        obj->IterateBody(map->instance_type(), size, &marking_visitor);
8353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
8363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MarkBit obj_mark_bit = Marking::MarkBitFrom(obj);
8383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SLOW_ASSERT(Marking::IsGrey(obj_mark_bit) ||
8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  (obj->IsFiller() && Marking::IsWhite(obj_mark_bit)));
8403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Marking::MarkBlack(obj_mark_bit);
8413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MemoryChunk::IncrementLiveBytesFromGC(obj->address(), size);
8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
8438f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch    if (marking_deque_.IsEmpty()) MarkingComplete(action);
8443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  allocated_ = 0;
8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  steps_count_++;
8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  steps_count_since_last_gc_++;
8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool speed_up = false;
8523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if ((steps_count_ % kAllocationMarkingFactorSpeedupInterval) == 0) {
8543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FLAG_trace_gc) {
8553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PrintF("Speed up marking after %d steps\n",
8563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch             static_cast<int>(kAllocationMarkingFactorSpeedupInterval));
8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    speed_up = true;
8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool space_left_is_very_small =
8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (old_generation_space_available_at_start_of_incremental_ < 10 * MB);
8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool only_1_nth_of_space_that_was_available_still_left =
8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (SpaceLeftInOldSpace() * (allocation_marking_factor_ + 1) <
8663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          old_generation_space_available_at_start_of_incremental_);
8673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (space_left_is_very_small ||
8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      only_1_nth_of_space_that_was_available_still_left) {
8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FLAG_trace_gc) PrintF("Speed up marking because of low space left\n");
8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    speed_up = true;
8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool size_of_old_space_multiplied_by_n_during_marking =
8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (heap_->PromotedTotalSize() >
8763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       (allocation_marking_factor_ + 1) *
8773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch           old_generation_space_used_at_start_of_incremental_);
8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (size_of_old_space_multiplied_by_n_during_marking) {
8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    speed_up = true;
8803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FLAG_trace_gc) {
8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PrintF("Speed up marking because of heap size increase\n");
8823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
8833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int64_t promoted_during_marking = heap_->PromotedTotalSize()
8863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      - old_generation_space_used_at_start_of_incremental_;
8873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  intptr_t delay = allocation_marking_factor_ * MB;
8883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  intptr_t scavenge_slack = heap_->MaxSemiSpaceSize();
8893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // We try to scan at at least twice the speed that we are allocating.
8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (promoted_during_marking > bytes_scanned_ / 2 + scavenge_slack + delay) {
8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (FLAG_trace_gc) {
8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PrintF("Speed up marking because marker was not keeping up\n");
8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    speed_up = true;
8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (speed_up) {
8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (state_ != MARKING) {
9003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (FLAG_trace_gc) {
9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        PrintF("Postponing speeding up marking until marking starts\n");
9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
9043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      allocation_marking_factor_ += kAllocationMarkingFactorSpeedup;
9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      allocation_marking_factor_ = static_cast<int>(
9063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          Min(kMaxAllocationMarkingFactor,
9073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              static_cast<intptr_t>(allocation_marking_factor_ * 1.3)));
9083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (FLAG_trace_gc) {
9093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        PrintF("Marking speed increased to %d\n", allocation_marking_factor_);
9103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
9113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
9123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
9133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_trace_incremental_marking || FLAG_trace_gc) {
9153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    double end = OS::TimeCurrentMillis();
9163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    double delta = (end - start);
9173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    longest_step_ = Max(longest_step_, delta);
9183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    steps_took_ += delta;
9193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    steps_took_since_last_gc_ += delta;
9203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
9213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
9223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid IncrementalMarking::ResetStepCounters() {
9253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  steps_count_ = 0;
9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  steps_took_ = 0;
9273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  longest_step_ = 0.0;
9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  old_generation_space_available_at_start_of_incremental_ =
9293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SpaceLeftInOldSpace();
9303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  old_generation_space_used_at_start_of_incremental_ =
9313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap_->PromotedTotalSize();
9323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  steps_count_since_last_gc_ = 0;
9333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  steps_took_since_last_gc_ = 0;
9343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bytes_rescanned_ = 0;
9353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  allocation_marking_factor_ = kInitialAllocationMarkingFactor;
9363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bytes_scanned_ = 0;
9373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
9383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint64_t IncrementalMarking::SpaceLeftInOldSpace() {
9413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSize();
9423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
9433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} }  // namespace v8::internal
945