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