12efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "code-stubs.h" 310b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org#include "compilation-cache.h" 32c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "cpu-profiler.h" 33c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "deoptimizer.h" 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "execution.h" 350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#include "gdb-jit.h" 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "global-handles.h" 37c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "heap-profiler.h" 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "ic-inl.h" 39c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "incremental-marking.h" 4043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "mark-compact.h" 41e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org#include "marking-thread.h" 42ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org#include "objects-visiting.h" 43c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "objects-visiting-inl.h" 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "stub-cache.h" 45e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org#include "sweeper-thread.h" 4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 50c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 51c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* Marking::kWhiteBitPattern = "00"; 52c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* Marking::kBlackBitPattern = "10"; 53c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* Marking::kGreyBitPattern = "11"; 54c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* Marking::kImpossibleBitPattern = "01"; 55c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 56c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 57ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// ------------------------------------------------------------------------- 5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// MarkCompactCollector 5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 60ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMarkCompactCollector::MarkCompactCollector() : // NOLINT 61ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#ifdef DEBUG 62ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org state_(IDLE), 63ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif 64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com sweep_precisely_(false), 65154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org reduce_memory_footprint_(false), 66154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org abort_incremental_marking_(false), 67e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org marking_parity_(ODD_MARKING_PARITY), 68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com compacting_(false), 69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com was_marked_incrementally_(false), 707c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org sweeping_pending_(false), 71750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org sequential_sweeping_(false), 72ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org tracer_(NULL), 73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com migration_slots_buffer_(NULL), 74ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org heap_(NULL), 757c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org code_flusher_(NULL), 76fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org encountered_weak_collections_(NULL), 77fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org code_to_deoptimize_(NULL) { } 78ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 79c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 80c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass VerifyMarkingVisitor: public ObjectVisitor { 81c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 82c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void VisitPointers(Object** start, Object** end) { 83c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Object** current = start; current < end; current++) { 84c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((*current)->IsHeapObject()) { 85c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* object = HeapObject::cast(*current); 86c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CHECK(HEAP->mark_compact_collector()->IsMarked(object)); 87c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 88c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 89c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 90003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 91003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org void VisitEmbeddedPointer(RelocInfo* rinfo) { 92003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); 9394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (!FLAG_weak_embedded_maps_in_optimized_code || !FLAG_collect_maps || 94068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org rinfo->host()->kind() != Code::OPTIMIZED_FUNCTION || 95003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org !rinfo->target_object()->IsMap() || 96003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org !Map::cast(rinfo->target_object())->CanTransition()) { 97003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org VisitPointer(rinfo->target_object_address()); 98003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 99003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyMarking(Address bottom, Address top) { 104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarkingVisitor visitor; 105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* object; 106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address next_object_must_be_here_or_later = bottom; 107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address current = bottom; 109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com current < top; 110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com current += kPointerSize) { 111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object = HeapObject::FromAddress(current); 112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (MarkCompactCollector::IsMarked(object)) { 113c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CHECK(current >= next_object_must_be_here_or_later); 114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object->Iterate(&visitor); 115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com next_object_must_be_here_or_later = current + object->Size(); 116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyMarking(NewSpace* space) { 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address end = space->top(); 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePageIterator it(space->bottom(), end); 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The bottom position is at the start of its page. Allows us to use 125ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org // page->area_start() as start of range on all pages. 126c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CHECK_EQ(space->bottom(), 127ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org NewSpacePage::FromAddress(space->bottom())->area_start()); 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* page = it.next(); 130ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address limit = it.has_next() ? page->area_end() : end; 131c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CHECK(limit == end || !page->Contains(end)); 132ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org VerifyMarking(page->area_start(), limit); 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyMarking(PagedSpace* space) { 138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PageIterator it(space); 139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = it.next(); 142ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org VerifyMarking(p->area_start(), p->area_end()); 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyMarking(Heap* heap) { 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarking(heap->old_pointer_space()); 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarking(heap->old_data_space()); 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarking(heap->code_space()); 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarking(heap->cell_space()); 15241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org VerifyMarking(heap->property_cell_space()); 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarking(heap->map_space()); 154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarking(heap->new_space()); 155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarkingVisitor visitor; 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LargeObjectIterator it(heap->lo_space()); 159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (MarkCompactCollector::IsMarked(obj)) { 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com obj->Iterate(&visitor); 162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass VerifyEvacuationVisitor: public ObjectVisitor { 170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void VisitPointers(Object** start, Object** end) { 172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Object** current = start; current < end; current++) { 173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((*current)->IsHeapObject()) { 174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* object = HeapObject::cast(*current); 175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); 176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyEvacuation(Address bottom, Address top) { 183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuationVisitor visitor; 184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* object; 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address next_object_must_be_here_or_later = bottom; 186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Address current = bottom; 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com current < top; 189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com current += kPointerSize) { 190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object = HeapObject::FromAddress(current); 191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (MarkCompactCollector::IsMarked(object)) { 192c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CHECK(current >= next_object_must_be_here_or_later); 193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object->Iterate(&visitor); 194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com next_object_must_be_here_or_later = current + object->Size(); 195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyEvacuation(NewSpace* space) { 201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePageIterator it(space->bottom(), space->top()); 202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuationVisitor visitor; 203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* page = it.next(); 206ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address current = page->area_start(); 207ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address limit = it.has_next() ? page->area_end() : space->top(); 208c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CHECK(limit == space->top() || !page->Contains(space->top())); 209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (current < limit) { 210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* object = HeapObject::FromAddress(current); 211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object->Iterate(&visitor); 212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com current += object->Size(); 213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyEvacuation(PagedSpace* space) { 219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PageIterator it(space); 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = it.next(); 223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (p->IsEvacuationCandidate()) continue; 224ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org VerifyEvacuation(p->area_start(), p->area_end()); 225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyEvacuation(Heap* heap) { 230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuation(heap->old_pointer_space()); 231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuation(heap->old_data_space()); 232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuation(heap->code_space()); 233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuation(heap->cell_space()); 23441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org VerifyEvacuation(heap->property_cell_space()); 235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuation(heap->map_space()); 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuation(heap->new_space()); 237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuationVisitor visitor; 239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap->IterateStrongRoots(&visitor, VISIT_ALL); 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 241c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif // VERIFY_HEAP 242ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 243ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 244c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef DEBUG 24546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgclass VerifyNativeContextSeparationVisitor: public ObjectVisitor { 246ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org public: 24746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org VerifyNativeContextSeparationVisitor() : current_native_context_(NULL) {} 248ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 249ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org void VisitPointers(Object** start, Object** end) { 250ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org for (Object** current = start; current < end; current++) { 251ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org if ((*current)->IsHeapObject()) { 252ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org HeapObject* object = HeapObject::cast(*current); 253ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org if (object->IsString()) continue; 254ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org switch (object->map()->instance_type()) { 255ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_FUNCTION_TYPE: 256ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org CheckContext(JSFunction::cast(object)->context()); 257ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org break; 258ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_GLOBAL_PROXY_TYPE: 25946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org CheckContext(JSGlobalProxy::cast(object)->native_context()); 260ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org break; 261ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_GLOBAL_OBJECT_TYPE: 262ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_BUILTINS_OBJECT_TYPE: 26346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org CheckContext(GlobalObject::cast(object)->native_context()); 264ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org break; 265ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_ARRAY_TYPE: 266ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_DATE_TYPE: 267ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_OBJECT_TYPE: 268ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_REGEXP_TYPE: 269ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org VisitPointer(HeapObject::RawField(object, JSObject::kMapOffset)); 270ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org break; 271ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case MAP_TYPE: 272ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org VisitPointer(HeapObject::RawField(object, Map::kPrototypeOffset)); 273ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org VisitPointer(HeapObject::RawField(object, Map::kConstructorOffset)); 274ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org break; 275ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case FIXED_ARRAY_TYPE: 276ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org if (object->IsContext()) { 277ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org CheckContext(object); 278ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } else { 279ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org FixedArray* array = FixedArray::cast(object); 280ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org int length = array->length(); 281ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org // Set array length to zero to prevent cycles while iterating 282ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org // over array bodies, this is easier than intrusive marking. 283ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org array->set_length(0); 284ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org array->IterateBody( 285ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org FIXED_ARRAY_TYPE, FixedArray::SizeFor(length), this); 286ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org array->set_length(length); 287ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } 288ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org break; 28941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CELL_TYPE: 290ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_PROXY_TYPE: 291ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case JS_VALUE_TYPE: 292ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case TYPE_FEEDBACK_INFO_TYPE: 293ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org object->Iterate(this); 294ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org break; 2957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org case DECLARED_ACCESSOR_INFO_TYPE: 2967c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org case EXECUTABLE_ACCESSOR_INFO_TYPE: 297ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case BYTE_ARRAY_TYPE: 298ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case CALL_HANDLER_INFO_TYPE: 299ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case CODE_TYPE: 300ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case FIXED_DOUBLE_ARRAY_TYPE: 301ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case HEAP_NUMBER_TYPE: 302ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case INTERCEPTOR_INFO_TYPE: 303ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case ODDBALL_TYPE: 304ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case SCRIPT_TYPE: 305ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org case SHARED_FUNCTION_INFO_TYPE: 306ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org break; 307ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org default: 308ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org UNREACHABLE(); 309ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } 310ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } 311ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } 312ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } 313ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 314ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org private: 315ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org void CheckContext(Object* context) { 316ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org if (!context->IsContext()) return; 31746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context* native_context = Context::cast(context)->native_context(); 31846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (current_native_context_ == NULL) { 31946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org current_native_context_ = native_context; 320ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } else { 32146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org CHECK_EQ(current_native_context_, native_context); 322ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } 323ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } 324ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 32546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context* current_native_context_; 326ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org}; 327ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 328ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 32946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgstatic void VerifyNativeContextSeparation(Heap* heap) { 330ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org HeapObjectIterator it(heap->code_space()); 331ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 332ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org for (Object* object = it.Next(); object != NULL; object = it.Next()) { 33346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org VerifyNativeContextSeparationVisitor visitor; 334ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org Code::cast(object)->CodeIterateBody(&visitor); 335ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } 336ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org} 337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 340d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid MarkCompactCollector::TearDown() { 341d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org AbortCompaction(); 342d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 343d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 344d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::AddEvacuationCandidate(Page* p) { 346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->MarkEvacuationCandidate(); 347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com evacuation_candidates_.Add(p); 348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 351994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgstatic void TraceFragmentation(PagedSpace* space) { 352994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org int number_of_pages = space->CountTotalPages(); 353ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org intptr_t reserved = (number_of_pages * space->AreaSize()); 354994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org intptr_t free = reserved - space->SizeOfObjects(); 355994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org PrintF("[%s]: %d pages, %d (%.1f%%) free\n", 356994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org AllocationSpaceName(space->identity()), 357994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org number_of_pages, 358994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<int>(free), 359994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<double>(free) * 100 / reserved); 360994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org} 361994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 362994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 363ab7dad4f999df008b590c74c2fe3d2e2c67ef7ffjkummerow@chromium.orgbool MarkCompactCollector::StartCompaction(CompactionMode mode) { 364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!compacting_) { 365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(evacuation_candidates_.length() == 0); 366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 36733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#ifdef ENABLE_GDB_JIT_INTERFACE 36833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // If GDBJIT interface is active disable compaction. 36933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (FLAG_gdbjit) return false; 37033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#endif 37133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CollectEvacuationCandidates(heap()->old_pointer_space()); 373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CollectEvacuationCandidates(heap()->old_data_space()); 374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 37556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org if (FLAG_compact_code_space && 37656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org (mode == NON_INCREMENTAL_COMPACTION || 37756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org FLAG_incremental_code_compaction)) { 378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CollectEvacuationCandidates(heap()->code_space()); 379994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } else if (FLAG_trace_fragmentation) { 380994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org TraceFragmentation(heap()->code_space()); 381994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 382994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 383994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (FLAG_trace_fragmentation) { 384994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org TraceFragmentation(heap()->map_space()); 385994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org TraceFragmentation(heap()->cell_space()); 38641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org TraceFragmentation(heap()->property_cell_space()); 387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists(); 390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->old_data_space()->EvictEvacuationCandidatesFromFreeLists(); 391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); 392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com compacting_ = evacuation_candidates_.length() > 0; 394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return compacting_; 397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 400061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.orgvoid MarkCompactCollector::CollectGarbage() { 401061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org // Make sure that Prepare() has been called. The individual steps below will 402061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org // update the state as they proceed. 403061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org ASSERT(state_ == PREPARE_GC); 404ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ASSERT(encountered_weak_collections_ == Smi::FromInt(0)); 405061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org 40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen MarkLiveObjects(); 407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(heap_->incremental_marking()->IsStopped()); 40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 409003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (FLAG_collect_maps) ClearNonLiveReferences(); 4109bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org 411ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ClearWeakCollections(); 4127c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 413c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_verify_heap) { 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarking(heap_); 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SweepSpaces(); 42043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4215f0b8ea679aeeacddb5e475301e6aad026ff8b4byangguo@chromium.org if (!FLAG_collect_maps) ReattachInitialMaps(); 42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 423ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org#ifdef DEBUG 42446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (FLAG_verify_native_context_separation) { 42546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org VerifyNativeContextSeparation(heap_); 426ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org } 427ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org#endif 428ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org 42994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#ifdef VERIFY_HEAP 43094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_optimized_code && 43194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org heap()->weak_embedded_maps_verification_enabled()) { 43294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org VerifyWeakEmbeddedMapsInOptimizedCode(); 43394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 434594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) { 435594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org VerifyOmittedMapChecks(); 4362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 43794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#endif 43894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Finish(); 4407276f14ca716596e0a0d17539516370c1f453847kasper.lund 441e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (marking_parity_ == EVEN_MARKING_PARITY) { 442e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org marking_parity_ = ODD_MARKING_PARITY; 443e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 444e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ASSERT(marking_parity_ == ODD_MARKING_PARITY); 445e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org marking_parity_ = EVEN_MARKING_PARITY; 446e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 447e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4487276f14ca716596e0a0d17539516370c1f453847kasper.lund tracer_ = NULL; 44943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 45043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 452c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { 454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PageIterator it(space); 455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = it.next(); 458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK(p->markbits()->IsClean()); 459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK_EQ(0, p->LiveBytes()); 460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 463c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org 464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { 465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePageIterator it(space->bottom(), space->top()); 466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* p = it.next(); 469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK(p->markbits()->IsClean()); 470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CHECK_EQ(0, p->LiveBytes()); 471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 474c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org 475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::VerifyMarkbitsAreClean() { 476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarkbitsAreClean(heap_->old_pointer_space()); 477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarkbitsAreClean(heap_->old_data_space()); 478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarkbitsAreClean(heap_->code_space()); 479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarkbitsAreClean(heap_->cell_space()); 48041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org VerifyMarkbitsAreClean(heap_->property_cell_space()); 481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarkbitsAreClean(heap_->map_space()); 482c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarkbitsAreClean(heap_->new_space()); 483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LargeObjectIterator it(heap_->lo_space()); 485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark_bit = Marking::MarkBitFrom(obj); 487c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CHECK(Marking::IsWhite(mark_bit)); 488c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); 489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 49194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 49294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 49394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgvoid MarkCompactCollector::VerifyWeakEmbeddedMapsInOptimizedCode() { 49494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org HeapObjectIterator code_iterator(heap()->code_space()); 49594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org for (HeapObject* obj = code_iterator.Next(); 49694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org obj != NULL; 49794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org obj = code_iterator.Next()) { 49894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Code* code = Code::cast(obj); 49994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org if (code->kind() != Code::OPTIMIZED_FUNCTION) continue; 500fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (WillBeDeoptimized(code)) continue; 50194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org code->VerifyEmbeddedMapsDependency(); 50294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org } 50394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 5042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org 5052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org 506594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MarkCompactCollector::VerifyOmittedMapChecks() { 5072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org HeapObjectIterator iterator(heap()->map_space()); 5082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org for (HeapObject* obj = iterator.Next(); 5092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org obj != NULL; 5102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org obj = iterator.Next()) { 5112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org Map* map = Map::cast(obj); 512594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org map->VerifyOmittedMapChecks(); 5132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 5142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org} 515c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif // VERIFY_HEAP 516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 518394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic void ClearMarkbitsInPagedSpace(PagedSpace* space) { 519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PageIterator it(space); 520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Bitmap::Clear(it.next()); 523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 527394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic void ClearMarkbitsInNewSpace(NewSpace* space) { 528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); 529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Bitmap::Clear(it.next()); 532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 536394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid MarkCompactCollector::ClearMarkbits() { 537394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ClearMarkbitsInPagedSpace(heap_->code_space()); 538394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ClearMarkbitsInPagedSpace(heap_->map_space()); 539394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ClearMarkbitsInPagedSpace(heap_->old_pointer_space()); 540394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ClearMarkbitsInPagedSpace(heap_->old_data_space()); 541394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ClearMarkbitsInPagedSpace(heap_->cell_space()); 54241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ClearMarkbitsInPagedSpace(heap_->property_cell_space()); 543394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ClearMarkbitsInNewSpace(heap_->new_space()); 544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 545394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LargeObjectIterator it(heap_->lo_space()); 546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark_bit = Marking::MarkBitFrom(obj); 548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mark_bit.Clear(); 549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mark_bit.Next().Clear(); 550fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Page::FromAddress(obj->address())->ResetProgressBar(); 55128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Page::FromAddress(obj->address())->ResetLiveBytes(); 552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 556e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgvoid MarkCompactCollector::StartSweeperThreads() { 5577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org sweeping_pending_ = true; 558e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org for (int i = 0; i < FLAG_sweeper_threads; i++) { 559876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org isolate()->sweeper_threads()[i]->StartSweeping(); 560e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 561e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 562e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 563e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 564e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgvoid MarkCompactCollector::WaitUntilSweepingCompleted() { 565750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org ASSERT(sweeping_pending_ == true); 566750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org for (int i = 0; i < FLAG_sweeper_threads; i++) { 567876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org isolate()->sweeper_threads()[i]->WaitForSweeperThread(); 568e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 569750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org sweeping_pending_ = false; 570750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org StealMemoryFromSweeperThreads(heap()->paged_space(OLD_DATA_SPACE)); 571750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org StealMemoryFromSweeperThreads(heap()->paged_space(OLD_POINTER_SPACE)); 572750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); 573750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes(); 574e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 575e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 576e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 577e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgintptr_t MarkCompactCollector:: 578e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org StealMemoryFromSweeperThreads(PagedSpace* space) { 579e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org intptr_t freed_bytes = 0; 580e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org for (int i = 0; i < FLAG_sweeper_threads; i++) { 581876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org freed_bytes += isolate()->sweeper_threads()[i]->StealMemory(space); 582e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 5838432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org space->AddToAccountingStats(freed_bytes); 5848432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org space->DecrementUnsweptFreeBytes(freed_bytes); 585e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org return freed_bytes; 586e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 587e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 588e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 589e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgbool MarkCompactCollector::AreSweeperThreadsActivated() { 590876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org return isolate()->sweeper_threads() != NULL; 591e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 592e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 593e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 5942f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.orgbool MarkCompactCollector::IsConcurrentSweepingInProgress() { 5957c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org return sweeping_pending_; 5962f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org} 5972f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 5982f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 599e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgvoid MarkCompactCollector::MarkInParallel() { 600e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org for (int i = 0; i < FLAG_marking_threads; i++) { 601876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org isolate()->marking_threads()[i]->StartMarking(); 602e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 603e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 604e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 605e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 606e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgvoid MarkCompactCollector::WaitUntilMarkingCompleted() { 607e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org for (int i = 0; i < FLAG_marking_threads; i++) { 608876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org isolate()->marking_threads()[i]->WaitForMarkingThread(); 609e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 610e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 611e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 612e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 613c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool Marking::TransferMark(Address old_start, Address new_start) { 614c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // This is only used when resizing an object. 615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(MemoryChunk::FromAddress(old_start) == 616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::FromAddress(new_start)); 617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the mark doesn't move, we don't check the color of the object. 619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // It doesn't matter whether the object is black, since it hasn't changed 620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // size, so the adjustment to the live data count will be zero anyway. 621c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (old_start == new_start) return false; 622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit new_mark_bit = MarkBitFrom(new_start); 624c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit old_mark_bit = MarkBitFrom(old_start); 625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG 627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ObjectColor old_color = Color(old_mark_bit); 628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (Marking::IsBlack(old_mark_bit)) { 631c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_mark_bit.Clear(); 632c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsWhite(old_mark_bit)); 633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Marking::MarkBlack(new_mark_bit); 634c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return true; 635c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (Marking::IsGrey(old_mark_bit)) { 636c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(heap_->incremental_marking()->IsMarking()); 637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_mark_bit.Clear(); 638c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com old_mark_bit.Next().Clear(); 639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsWhite(old_mark_bit)); 640c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->incremental_marking()->WhiteToGreyAndPush( 641c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject::FromAddress(new_start), new_mark_bit); 642c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->incremental_marking()->RestartIfNotMarking(); 643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 644c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 645c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG 646c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ObjectColor new_color = Color(new_mark_bit); 647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(new_color == old_color); 648c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 650c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return false; 651c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* AllocationSpaceName(AllocationSpace space) { 655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com switch (space) { 656c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case NEW_SPACE: return "NEW_SPACE"; 657c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case OLD_POINTER_SPACE: return "OLD_POINTER_SPACE"; 658c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case OLD_DATA_SPACE: return "OLD_DATA_SPACE"; 659c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case CODE_SPACE: return "CODE_SPACE"; 660c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case MAP_SPACE: return "MAP_SPACE"; 661c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case CELL_SPACE: return "CELL_SPACE"; 66241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case PROPERTY_CELL_SPACE: 66341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return "PROPERTY_CELL_SPACE"; 664c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case LO_SPACE: return "LO_SPACE"; 665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com default: 666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UNREACHABLE(); 667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return NULL; 670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 671c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 672c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 673994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org// Returns zero for pages that have so little fragmentation that it is not 674994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org// worth defragmenting them. Otherwise a positive integer that gives an 675994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org// estimate of fragmentation on an arbitrary scale. 676994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgstatic int FreeListFragmentation(PagedSpace* space, Page* p) { 677994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org // If page was not swept then there are no free list items on it. 678994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (!p->WasSwept()) { 679994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (FLAG_trace_fragmentation) { 680994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org PrintF("%p [%s]: %d bytes live (unswept)\n", 681994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org reinterpret_cast<void*>(p), 682994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org AllocationSpaceName(space->identity()), 683994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org p->LiveBytes()); 684994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 685994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org return 0; 686994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 687994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 688e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org PagedSpace::SizeStats sizes; 689e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org space->ObtainFreeListStatistics(p, &sizes); 690994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 691994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org intptr_t ratio; 692994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org intptr_t ratio_threshold; 693ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org intptr_t area_size = space->AreaSize(); 694994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (space->identity() == CODE_SPACE) { 695994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / 696ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org area_size; 697994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org ratio_threshold = 10; 698994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } else { 699994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / 700ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org area_size; 701994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org ratio_threshold = 15; 702994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 703994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 704994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (FLAG_trace_fragmentation) { 705994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org PrintF("%p [%s]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", 706994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org reinterpret_cast<void*>(p), 707994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org AllocationSpaceName(space->identity()), 708994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<int>(sizes.small_size_), 709994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<double>(sizes.small_size_ * 100) / 710ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org area_size, 711994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<int>(sizes.medium_size_), 712994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<double>(sizes.medium_size_ * 100) / 713ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org area_size, 714994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<int>(sizes.large_size_), 715994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<double>(sizes.large_size_ * 100) / 716ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org area_size, 717994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<int>(sizes.huge_size_), 718994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<double>(sizes.huge_size_ * 100) / 719ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org area_size, 720994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org (ratio > ratio_threshold) ? "[fragmented]" : ""); 721994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 722994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 723ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org if (FLAG_always_compact && sizes.Total() != area_size) { 724994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org return 1; 725994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 726994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 727994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (ratio <= ratio_threshold) return 0; // Not fragmented. 728994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 729994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org return static_cast<int>(ratio - ratio_threshold); 730994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org} 731994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 732994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { 734c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(space->identity() == OLD_POINTER_SPACE || 735c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space->identity() == OLD_DATA_SPACE || 736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space->identity() == CODE_SPACE); 737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 738de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org static const int kMaxMaxEvacuationCandidates = 1000; 7391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int number_of_pages = space->CountTotalPages(); 740de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org int max_evacuation_candidates = 741471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org static_cast<int>(sqrt(number_of_pages / 2.0) + 1); 7421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 7431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (FLAG_stress_compaction || FLAG_always_compact) { 7441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org max_evacuation_candidates = kMaxMaxEvacuationCandidates; 7451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 7461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 7471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org class Candidate { 7481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org public: 7491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Candidate() : fragmentation_(0), page_(NULL) { } 7501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Candidate(int f, Page* p) : fragmentation_(f), page_(p) { } 7511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 7521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int fragmentation() { return fragmentation_; } 7531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Page* page() { return page_; } 7541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 7551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org private: 7561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int fragmentation_; 7571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Page* page_; 7581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org }; 7591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 760994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org enum CompactionMode { 761994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org COMPACT_FREE_LISTS, 762994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org REDUCE_MEMORY_FOOTPRINT 763994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org }; 764994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 765994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org CompactionMode mode = COMPACT_FREE_LISTS; 766994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 767ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org intptr_t reserved = number_of_pages * space->AreaSize(); 768994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org intptr_t over_reserved = reserved - space->SizeOfObjects(); 769994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static const intptr_t kFreenessThreshold = 50; 770994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 771471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (reduce_memory_footprint_ && over_reserved >= space->AreaSize()) { 772de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org // If reduction of memory footprint was requested, we are aggressive 773de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org // about choosing pages to free. We expect that half-empty pages 774de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org // are easier to compact so slightly bump the limit. 775471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org mode = REDUCE_MEMORY_FOOTPRINT; 776471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org max_evacuation_candidates += 2; 777471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 778471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 779994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 780471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (over_reserved > reserved / 3 && over_reserved >= 2 * space->AreaSize()) { 781de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org // If over-usage is very high (more than a third of the space), we 782de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org // try to free all mostly empty pages. We expect that almost empty 783de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org // pages are even easier to compact so bump the limit even more. 784471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org mode = REDUCE_MEMORY_FOOTPRINT; 785471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org max_evacuation_candidates *= 2; 786471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } 787994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 788471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (FLAG_trace_fragmentation && mode == REDUCE_MEMORY_FOOTPRINT) { 789bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org PrintF("Estimated over reserved memory: %.1f / %.1f MB (threshold %d), " 790bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org "evacuation candidate limit: %d\n", 791471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org static_cast<double>(over_reserved) / MB, 792471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org static_cast<double>(reserved) / MB, 793bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org static_cast<int>(kFreenessThreshold), 794bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org max_evacuation_candidates); 795994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 796994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 797994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org intptr_t estimated_release = 0; 798994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 7991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Candidate candidates[kMaxMaxEvacuationCandidates]; 8001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 801de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org max_evacuation_candidates = 802de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org Min(kMaxMaxEvacuationCandidates, max_evacuation_candidates); 803de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org 804c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int count = 0; 8051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int fragmentation = 0; 8061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Candidate* least = NULL; 807994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 808994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org PageIterator it(space); 809994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (it.has_next()) it.next(); // Never compact the first page. 810994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 811c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 812c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = it.next(); 8131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org p->ClearEvacuationCandidate(); 814994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 815b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (FLAG_stress_compaction) { 816b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org unsigned int counter = space->heap()->ms_count(); 817b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org uintptr_t page_number = reinterpret_cast<uintptr_t>(p) >> kPageSizeBits; 8181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if ((counter & 1) == (page_number & 1)) fragmentation = 1; 819994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } else if (mode == REDUCE_MEMORY_FOOTPRINT) { 820994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org // Don't try to release too many pages. 821bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (estimated_release >= over_reserved) { 822994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org continue; 823994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 824994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 825994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org intptr_t free_bytes = 0; 826994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 827994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (!p->WasSwept()) { 828ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org free_bytes = (p->area_size() - p->LiveBytes()); 829994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } else { 830e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org PagedSpace::SizeStats sizes; 831e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org space->ObtainFreeListStatistics(p, &sizes); 832994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org free_bytes = sizes.Total(); 833994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 834994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 835ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org int free_pct = static_cast<int>(free_bytes * 100) / p->area_size(); 836994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 837994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (free_pct >= kFreenessThreshold) { 838bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org estimated_release += free_bytes; 839994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org fragmentation = free_pct; 840994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } else { 841994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org fragmentation = 0; 842994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 843994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 844994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org if (FLAG_trace_fragmentation) { 845994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org PrintF("%p [%s]: %d (%.2f%%) free %s\n", 846994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org reinterpret_cast<void*>(p), 847994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org AllocationSpaceName(space->identity()), 848994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org static_cast<int>(free_bytes), 849ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org static_cast<double>(free_bytes * 100) / p->area_size(), 850994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org (fragmentation > 0) ? "[fragmented]" : ""); 851994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org } 852b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } else { 853994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org fragmentation = FreeListFragmentation(space, p); 854b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } 855994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 8561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (fragmentation != 0) { 8571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (count < max_evacuation_candidates) { 8581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org candidates[count++] = Candidate(fragmentation, p); 8591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } else { 8601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (least == NULL) { 8611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org for (int i = 0; i < max_evacuation_candidates; i++) { 8621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (least == NULL || 8631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org candidates[i].fragmentation() < least->fragmentation()) { 8641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org least = candidates + i; 8651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 8661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 8671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 8681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (least->fragmentation() < fragmentation) { 8691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org *least = Candidate(fragmentation, p); 8701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org least = NULL; 8711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 8721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 873c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 874c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 875994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org 8761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org for (int i = 0; i < count; i++) { 8771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org AddEvacuationCandidate(candidates[i].page()); 8781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 879c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 880c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (count > 0 && FLAG_trace_fragmentation) { 881c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PrintF("Collected %d evacuation candidates for space %s\n", 882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com count, 883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AllocationSpaceName(space->identity())); 884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 886c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 887c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 888c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::AbortCompaction() { 889c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (compacting_) { 890c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int npages = evacuation_candidates_.length(); 891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < npages; i++) { 892c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = evacuation_candidates_[i]; 893c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); 894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->ClearEvacuationCandidate(); 895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 896c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com compacting_ = false; 898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com evacuation_candidates_.Rewind(0); 899c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com invalidated_code_.Rewind(0); 900c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 901c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, evacuation_candidates_.length()); 902c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 903c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 904c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 905061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.orgvoid MarkCompactCollector::Prepare(GCTracer* tracer) { 906c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com was_marked_incrementally_ = heap()->incremental_marking()->IsMarking(); 907c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 908061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org // Rather than passing the tracer around we stash it in a static member 909061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org // variable. 910061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org tracer_ = tracer; 911061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org 91243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG 91343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(state_ == IDLE); 91443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen state_ = PREPARE_GC; 91543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 91643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!FLAG_never_compact || !FLAG_always_compact); 91843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 919750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (IsConcurrentSweepingInProgress()) { 920e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // Instead of waiting we could also abort the sweeper threads here. 921e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org WaitUntilSweepingCompleted(); 922e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 923e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 924bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com // Clear marking bits if incremental marking is aborted. 925bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com if (was_marked_incrementally_ && abort_incremental_marking_) { 926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->incremental_marking()->Abort(); 927394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ClearMarkbits(); 928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AbortCompaction(); 929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com was_marked_incrementally_ = false; 930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 931c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 932c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Don't start compaction if we are in the middle of incremental 933c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // marking cycle. We did not collect any slots. 934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!FLAG_never_compact && !was_marked_incrementally_) { 935ab7dad4f999df008b590c74c2fe3d2e2c67ef7ffjkummerow@chromium.org StartCompaction(NON_INCREMENTAL_COMPACTION); 936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 9387c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org PagedSpaces spaces(heap()); 939b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org for (PagedSpace* space = spaces.next(); 940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space != NULL; 941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space = spaces.next()) { 942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space->PrepareForMarkCompact(); 943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 945c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 946394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!was_marked_incrementally_ && FLAG_verify_heap) { 947c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyMarkbitsAreClean(); 9489258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } 949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 95043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 95143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 95294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 95343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MarkCompactCollector::Finish() { 95443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG 95530ce411529579186181838984710b0b0980857aaricow@chromium.org ASSERT(state_ == SWEEP_SPACES || state_ == RELOCATE_OBJECTS); 95643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen state_ = IDLE; 95743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The stub cache is not traversed during GC; clear the cache to 95943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // force lazy re-initialization of it. This must be done after the 96043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // GC, because it relies on the new address of certain old space 96143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // objects (empty string, illegal builtin). 962876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org isolate()->stub_cache()->Clear(); 963003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 964fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (code_to_deoptimize_ != Smi::FromInt(0)) { 965fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // Convert the linked list of Code objects into a ZoneList. 966fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Zone zone(isolate()); 967fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org ZoneList<Code*> codes(4, &zone); 968fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 969fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Object *list = code_to_deoptimize_; 970fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org while (list->IsCode()) { 971fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Code *code = Code::cast(list); 972fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org list = code->code_to_deoptimize_link(); 973fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org codes.Add(code, &zone); 974fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // Destroy the link and don't ever try to deoptimize this code again. 975fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org code->set_code_to_deoptimize_link(Smi::FromInt(0)); 976fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 977fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org code_to_deoptimize_ = Smi::FromInt(0); 978fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 979fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Deoptimizer::DeoptimizeCodeList(isolate(), &codes); 980fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 98143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 98243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 98343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 984ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// ------------------------------------------------------------------------- 98543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Phase 1: tracing and marking live objects. 98643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// before: all objects are in normal state. 98743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// after: a live object's map pointer is marked as '00'. 98843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 98943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Marking all live objects in the heap as part of mark-sweep or mark-compact 99043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// collection. Before marking, all objects are in their normal state. After 99143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// marking, live objects' map pointers are marked indicating that the object 99243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// has been found reachable. 99343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 99443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The marking algorithm is a (mostly) depth-first (because of possible stack 99543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// overflow) traversal of the graph of objects reachable from the roots. It 99643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// uses an explicit stack of pointers rather than recursion. The young 99743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// generation's inactive ('from') space is used as a marking stack. The 99843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// objects in the marking stack are the ones that have been reached and marked 99943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// but their children have not yet been visited. 100043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 100143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The marking stack can overflow during traversal. In that case, we set an 100243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// overflow flag. When the overflow flag is set, we continue marking objects 100343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// reachable from the objects on the marking stack, but no longer push them on 100443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the marking stack. Instead, we mark them as both marked and overflowed. 100543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// When the stack is in the overflowed state, objects marked as overflowed 100643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// have been reached and marked but their children have not been visited yet. 100743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// After emptying the marking stack, we clear the overflow flag and traverse 100843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the heap looking for objects marked as overflowed, push them on the stack, 100943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and continue with marking. This process repeats until all reachable 101043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// objects have been marked. 101143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1012c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid CodeFlusher::ProcessJSFunctionCandidates() { 1013c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); 101489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Object* undefined = isolate_->heap()->undefined_value(); 1015a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1016c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org JSFunction* candidate = jsfunction_candidates_head_; 1017c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org JSFunction* next_candidate; 1018c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org while (candidate != NULL) { 1019c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org next_candidate = GetNextCandidate(candidate); 102089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org ClearNextCandidate(candidate, undefined); 1021a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1022c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org SharedFunctionInfo* shared = candidate->shared(); 1023a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1024c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Code* code = shared->code(); 1025c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org MarkBit code_mark = Marking::MarkBitFrom(code); 1026c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (!code_mark.Get()) { 1027837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (FLAG_trace_code_flushing && shared->is_compiled()) { 1028b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF("[code-flushing clears: "); 1029b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org shared->ShortPrint(); 1030b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF(" - age: %d]\n", code->GetAge()); 1031837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org } 1032c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org shared->set_code(lazy_compile); 1033c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org candidate->set_code(lazy_compile); 10349768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org } else { 10359768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org candidate->set_code(code); 1036a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1038c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // We are in the middle of a GC cycle so the write barrier in the code 1039c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // setter did not record the slot update and we have to do that manually. 1040c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Address slot = candidate->address() + JSFunction::kCodeEntryOffset; 1041c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot)); 1042c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org isolate_->heap()->mark_compact_collector()-> 1043c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org RecordCodeEntrySlot(slot, target); 1044b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org 1045c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Object** shared_code_slot = 1046c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org HeapObject::RawField(shared, SharedFunctionInfo::kCodeOffset); 1047c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org isolate_->heap()->mark_compact_collector()-> 1048c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org RecordSlot(shared_code_slot, shared_code_slot, *shared_code_slot); 1049a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1050c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org candidate = next_candidate; 1051a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1052a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1053c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org jsfunction_candidates_head_ = NULL; 1054c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org} 1055b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org 1056a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1057c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid CodeFlusher::ProcessSharedFunctionInfoCandidates() { 1058c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); 1059a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1060c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org SharedFunctionInfo* candidate = shared_function_info_candidates_head_; 1061c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org SharedFunctionInfo* next_candidate; 1062c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org while (candidate != NULL) { 1063c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org next_candidate = GetNextCandidate(candidate); 106489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org ClearNextCandidate(candidate); 1065a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 106664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Code* code = candidate->code(); 1067c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org MarkBit code_mark = Marking::MarkBitFrom(code); 1068c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (!code_mark.Get()) { 1069837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (FLAG_trace_code_flushing && candidate->is_compiled()) { 1070b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF("[code-flushing clears: "); 1071b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org candidate->ShortPrint(); 1072b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF(" - age: %d]\n", code->GetAge()); 1073837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org } 1074c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org candidate->set_code(lazy_compile); 1075c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 1076a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1077c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Object** code_slot = 1078c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset); 1079c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org isolate_->heap()->mark_compact_collector()-> 1080c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org RecordSlot(code_slot, code_slot, *code_slot); 1081a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1082c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org candidate = next_candidate; 1083a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1084a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1085c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org shared_function_info_candidates_head_ = NULL; 1086c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org} 1087a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1088a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 10894e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid CodeFlusher::ProcessOptimizedCodeMaps() { 10904e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org static const int kEntriesStart = SharedFunctionInfo::kEntriesStart; 10914e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org static const int kEntryLength = SharedFunctionInfo::kEntryLength; 10924e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org static const int kContextOffset = 0; 10934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org static const int kCodeOffset = 1; 10944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org static const int kLiteralsOffset = 2; 10954e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org STATIC_ASSERT(kEntryLength == 3); 10964e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 10974e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org SharedFunctionInfo* holder = optimized_code_map_holder_head_; 10984e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org SharedFunctionInfo* next_holder; 10994e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org while (holder != NULL) { 11004e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org next_holder = GetNextCodeMap(holder); 11014e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org ClearNextCodeMap(holder); 11024e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 11034e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); 11044e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int new_length = kEntriesStart; 11054e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org int old_length = code_map->length(); 11064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org for (int i = kEntriesStart; i < old_length; i += kEntryLength) { 11074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Code* code = Code::cast(code_map->get(i + kCodeOffset)); 11084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org MarkBit code_mark = Marking::MarkBitFrom(code); 11094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (!code_mark.Get()) { 11104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org continue; 11114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 11124e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 1113b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Update and record the context slot in the optimized code map. 11144e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Object** context_slot = HeapObject::RawField(code_map, 11154e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org FixedArray::OffsetOfElementAt(new_length)); 11164e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org code_map->set(new_length++, code_map->get(i + kContextOffset)); 11174e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org ASSERT(Marking::IsBlack( 11184e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Marking::MarkBitFrom(HeapObject::cast(*context_slot)))); 11194e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org isolate_->heap()->mark_compact_collector()-> 11204e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org RecordSlot(context_slot, context_slot, *context_slot); 11214e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 11224e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // Update and record the code slot in the optimized code map. 11234e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Object** code_slot = HeapObject::RawField(code_map, 11244e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org FixedArray::OffsetOfElementAt(new_length)); 11254e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org code_map->set(new_length++, code_map->get(i + kCodeOffset)); 11264e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org ASSERT(Marking::IsBlack( 11274e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Marking::MarkBitFrom(HeapObject::cast(*code_slot)))); 11284e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org isolate_->heap()->mark_compact_collector()-> 11294e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org RecordSlot(code_slot, code_slot, *code_slot); 11304e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 11314e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // Update and record the literals slot in the optimized code map. 11324e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Object** literals_slot = HeapObject::RawField(code_map, 11334e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org FixedArray::OffsetOfElementAt(new_length)); 11344e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org code_map->set(new_length++, code_map->get(i + kLiteralsOffset)); 11354e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org ASSERT(Marking::IsBlack( 11364e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Marking::MarkBitFrom(HeapObject::cast(*literals_slot)))); 11374e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org isolate_->heap()->mark_compact_collector()-> 11384e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org RecordSlot(literals_slot, literals_slot, *literals_slot); 11394e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 11404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 11414e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // Trim the optimized code map if entries have been removed. 11424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (new_length < old_length) { 11434e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org holder->TrimOptimizedCodeMap(old_length - new_length); 11444e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 11454e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 11464e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org holder = next_holder; 11474e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 11484e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 11494e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org optimized_code_map_holder_head_ = NULL; 11504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org} 11514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 11524e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 11539768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.orgvoid CodeFlusher::EvictCandidate(SharedFunctionInfo* shared_info) { 1154c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org // Make sure previous flushing decisions are revisited. 11559768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org isolate_->heap()->incremental_marking()->RecordWrites(shared_info); 11569768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org 1157837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (FLAG_trace_code_flushing) { 1158b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF("[code-flushing abandons function-info: "); 1159b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org shared_info->ShortPrint(); 1160b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF("]\n"); 1161837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org } 1162837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org 11639768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org SharedFunctionInfo* candidate = shared_function_info_candidates_head_; 11649768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org SharedFunctionInfo* next_candidate; 11659768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org if (candidate == shared_info) { 11669768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org next_candidate = GetNextCandidate(shared_info); 11679768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org shared_function_info_candidates_head_ = next_candidate; 11689768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org ClearNextCandidate(shared_info); 11699768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org } else { 11709768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org while (candidate != NULL) { 11719768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org next_candidate = GetNextCandidate(candidate); 11729768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org 11739768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org if (next_candidate == shared_info) { 11749768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org next_candidate = GetNextCandidate(shared_info); 11759768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org SetNextCandidate(candidate, next_candidate); 11769768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org ClearNextCandidate(shared_info); 11779768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org break; 11789768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org } 11799768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org 11809768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org candidate = next_candidate; 11819768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org } 11829768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org } 11839768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org} 11849768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org 11859768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org 1186e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid CodeFlusher::EvictCandidate(JSFunction* function) { 1187e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org ASSERT(!function->next_function_link()->IsUndefined()); 1188e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Object* undefined = isolate_->heap()->undefined_value(); 1189e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 1190c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org // Make sure previous flushing decisions are revisited. 119132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org isolate_->heap()->incremental_marking()->RecordWrites(function); 1192c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org isolate_->heap()->incremental_marking()->RecordWrites(function->shared()); 119332280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org 1194837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (FLAG_trace_code_flushing) { 1195b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF("[code-flushing abandons closure: "); 1196b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org function->shared()->ShortPrint(); 1197b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF("]\n"); 1198837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org } 1199837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org 1200e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org JSFunction* candidate = jsfunction_candidates_head_; 1201e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org JSFunction* next_candidate; 1202e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (candidate == function) { 1203e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org next_candidate = GetNextCandidate(function); 1204e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org jsfunction_candidates_head_ = next_candidate; 1205e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org ClearNextCandidate(function, undefined); 1206e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } else { 1207e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org while (candidate != NULL) { 1208e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org next_candidate = GetNextCandidate(candidate); 1209e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 1210e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (next_candidate == function) { 1211e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org next_candidate = GetNextCandidate(function); 1212e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org SetNextCandidate(candidate, next_candidate); 1213e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org ClearNextCandidate(function, undefined); 12149768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org break; 1215e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1216e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 1217e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org candidate = next_candidate; 1218e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1219e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1220e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 1221e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 1222e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 12234e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid CodeFlusher::EvictOptimizedCodeMap(SharedFunctionInfo* code_map_holder) { 12244e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org ASSERT(!FixedArray::cast(code_map_holder->optimized_code_map())-> 12254e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org get(SharedFunctionInfo::kNextMapIndex)->IsUndefined()); 12264e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 12274e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org // Make sure previous flushing decisions are revisited. 12284e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org isolate_->heap()->incremental_marking()->RecordWrites(code_map_holder); 12294e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 1230837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org if (FLAG_trace_code_flushing) { 1231b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF("[code-flushing abandons code-map: "); 1232b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org code_map_holder->ShortPrint(); 1233b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org PrintF("]\n"); 1234837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org } 1235837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org 12364e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org SharedFunctionInfo* holder = optimized_code_map_holder_head_; 12374e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org SharedFunctionInfo* next_holder; 12384e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (holder == code_map_holder) { 12394e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org next_holder = GetNextCodeMap(code_map_holder); 12404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org optimized_code_map_holder_head_ = next_holder; 12414e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org ClearNextCodeMap(code_map_holder); 12424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } else { 12434e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org while (holder != NULL) { 12444e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org next_holder = GetNextCodeMap(holder); 12454e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 12464e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (next_holder == code_map_holder) { 12474e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org next_holder = GetNextCodeMap(code_map_holder); 12484e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org SetNextCodeMap(holder, next_holder); 12494e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org ClearNextCodeMap(code_map_holder); 12504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org break; 12514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 12524e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 12534e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org holder = next_holder; 12544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 12554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 12564e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org} 12574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 12584e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 1259e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid CodeFlusher::EvictJSFunctionCandidates() { 1260e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org JSFunction* candidate = jsfunction_candidates_head_; 1261e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org JSFunction* next_candidate; 1262e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org while (candidate != NULL) { 1263e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org next_candidate = GetNextCandidate(candidate); 12647c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org EvictCandidate(candidate); 1265e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org candidate = next_candidate; 1266e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 12677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org ASSERT(jsfunction_candidates_head_ == NULL); 1268e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 1269e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 1270e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 1271e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid CodeFlusher::EvictSharedFunctionInfoCandidates() { 1272e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org SharedFunctionInfo* candidate = shared_function_info_candidates_head_; 1273e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org SharedFunctionInfo* next_candidate; 1274e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org while (candidate != NULL) { 1275e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org next_candidate = GetNextCandidate(candidate); 12767c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org EvictCandidate(candidate); 1277e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org candidate = next_candidate; 1278e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 12797c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org ASSERT(shared_function_info_candidates_head_ == NULL); 1280e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 1281e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 1282e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 12834e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid CodeFlusher::EvictOptimizedCodeMaps() { 12844e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org SharedFunctionInfo* holder = optimized_code_map_holder_head_; 12854e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org SharedFunctionInfo* next_holder; 12864e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org while (holder != NULL) { 12874e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org next_holder = GetNextCodeMap(holder); 12884e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org EvictOptimizedCodeMap(holder); 12894e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org holder = next_holder; 12904e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 12914e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org ASSERT(optimized_code_map_holder_head_ == NULL); 12924e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org} 12934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 12944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 1295e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid CodeFlusher::IteratePointersToFromSpace(ObjectVisitor* v) { 1296e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org Heap* heap = isolate_->heap(); 1297e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 1298e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org JSFunction** slot = &jsfunction_candidates_head_; 1299e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org JSFunction* candidate = jsfunction_candidates_head_; 1300e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org while (candidate != NULL) { 1301e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (heap->InFromSpace(candidate)) { 1302e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org v->VisitPointer(reinterpret_cast<Object**>(slot)); 1303e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1304e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org candidate = GetNextCandidate(*slot); 1305e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org slot = GetNextCandidateSlot(*slot); 1306e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 1307e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org} 1308e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 1309e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 1310ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMarkCompactCollector::~MarkCompactCollector() { 1311ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (code_flusher_ != NULL) { 1312ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org delete code_flusher_; 1313ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org code_flusher_ = NULL; 1314ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 1315ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 1316ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 131731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 13185a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgstatic inline HeapObject* ShortCircuitConsString(Object** p) { 13194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Optimization: If the heap object pointed to by p is a non-internalized 1320ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // cons string whose right substring is HEAP->empty_string, update 13219258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // it in place to its left substring. Return the updated value. 132231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // 132331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // Here we assume that if we change *p, we replace it with a heap object 13242efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // (i.e., the left substring of a cons string is always a heap object). 132531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // 132631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // The check performed is: 13274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // object->IsConsString() && !object->IsInternalizedString() && 1328ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // (ConsString::cast(object)->second() == HEAP->empty_string()) 132931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // except the maps for the object and its possible substrings might be 133031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // marked. 133131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager HeapObject* object = HeapObject::cast(*p); 1332b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (!FLAG_clever_optimizations) return object; 1333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Map* map = object->map(); 1334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com InstanceType type = map->instance_type(); 1335d1e3e722d649dfcccf8699a801743c9a5426b0bckasperl@chromium.org if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object; 133631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 13371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Object* second = reinterpret_cast<ConsString*>(object)->second(); 1338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Heap* heap = map->GetHeap(); 1339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (second != heap->empty_string()) { 134068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return object; 134168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 134231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 134331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // Since we don't have the object's start, it is impossible to update the 134430ce411529579186181838984710b0b0980857aaricow@chromium.org // page dirty marks. Therefore, we only replace the string with its left 134530ce411529579186181838984710b0b0980857aaricow@chromium.org // substring when page dirty marks do not change. 13461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Object* first = reinterpret_cast<ConsString*>(object)->first(); 1347ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (!heap->InNewSpace(object) && heap->InNewSpace(first)) return object; 134831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 134931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager *p = first; 135031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager return HeapObject::cast(first); 135131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager} 135231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 135331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 1354b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor 1355b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { 135643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 1357304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id, 1358304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Map* map, HeapObject* obj); 1359304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1360304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org static void ObjectStatsCountFixedArray( 1361304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FixedArrayBase* fixed_array, 1362304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FixedArraySubInstanceType fast_type, 1363304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FixedArraySubInstanceType dictionary_type); 1364304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1365b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org template<MarkCompactMarkingVisitor::VisitorId id> 136628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org class ObjectStatsTracker { 136728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org public: 1368753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org static inline void Visit(Map* map, HeapObject* obj); 136928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org }; 137028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org 1371753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org static void Initialize(); 1372ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 1373ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org INLINE(static void VisitPointer(Heap* heap, Object** p)) { 1374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkObjectByPointer(heap->mark_compact_collector(), p, p); 137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13772ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) { 137843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Mark all objects pointed to in [start, end). 137943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const int kMinRangeForMarkingRecursion = 64; 138043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (end - start >= kMinRangeForMarkingRecursion) { 13812ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org if (VisitUnmarkedObjects(heap, start, end)) return; 138243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We are close to a stack overflow, so just mark the objects. 138343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkCompactCollector* collector = heap->mark_compact_collector(); 1385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (Object** p = start; p < end; p++) { 13862ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org MarkObjectByPointer(collector, start, p); 13877a96c2a24221ccb98eb3fbe4f5618ef9076cf55fjkummerow@chromium.org } 13887a96c2a24221ccb98eb3fbe4f5618ef9076cf55fjkummerow@chromium.org } 13897a96c2a24221ccb98eb3fbe4f5618ef9076cf55fjkummerow@chromium.org 139033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // Marks the object black and pushes it on the marking stack. 1391b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org INLINE(static void MarkObject(Heap* heap, HeapObject* object)) { 1392b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkBit mark = Marking::MarkBitFrom(object); 1393b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org heap->mark_compact_collector()->MarkObject(object, mark); 1394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 139633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // Marks the object black without pushing it on the marking stack. 139733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // Returns true if object needed marking and false otherwise. 139833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) { 139933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org MarkBit mark_bit = Marking::MarkBitFrom(object); 140033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (!mark_bit.Get()) { 140133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org heap->mark_compact_collector()->SetMark(object, mark_bit); 140233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org return true; 140333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 140433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org return false; 140533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 140633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 140743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Mark object pointed to by p. 1408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, 1409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object** anchor_slot, 1410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object** p)) { 141131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager if (!(*p)->IsHeapObject()) return; 141231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager HeapObject* object = ShortCircuitConsString(p); 1413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com collector->RecordSlot(anchor_slot, p, object); 1414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark = Marking::MarkBitFrom(object); 1415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com collector->MarkObject(object, mark); 141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 141743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1418ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 141943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Visit an unmarked object. 1420c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, 1421c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org HeapObject* obj)) { 142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG 1423c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(Isolate::Current()->heap()->Contains(obj)); 1424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!HEAP->mark_compact_collector()->IsMarked(obj)); 142543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 142643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Map* map = obj->map(); 1427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Heap* heap = obj->GetHeap(); 1428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark = Marking::MarkBitFrom(obj); 1429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap->mark_compact_collector()->SetMark(obj, mark); 143043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Mark the map pointer and the body. 1431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit map_mark = Marking::MarkBitFrom(map); 1432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap->mark_compact_collector()->MarkObject(map, map_mark); 1433ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org IterateBody(map, obj); 143443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 143543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 14362ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org // Visit all unmarked objects pointed to by [start, end). 143743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns false if the operation fails (lack of stack space). 14382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org INLINE(static bool VisitUnmarkedObjects(Heap* heap, 14392ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org Object** start, 14402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org Object** end)) { 144143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return false is we are close to the stack limit. 1442ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org StackLimitCheck check(heap->isolate()); 144343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (check.HasOverflowed()) return false; 144443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1445c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org MarkCompactCollector* collector = heap->mark_compact_collector(); 144643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Visit the unmarked objects. 14472ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org for (Object** p = start; p < end; p++) { 1448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object* o = *p; 1449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!o->IsHeapObject()) continue; 14502ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org collector->RecordSlot(start, p, o); 1451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* obj = HeapObject::cast(o); 1452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark = Marking::MarkBitFrom(obj); 1453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mark.Get()) continue; 1454c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org VisitUnmarkedObject(collector, obj); 145543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 145643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 145743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1458ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 1459c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org INLINE(static void BeforeVisitingSharedFunctionInfo(HeapObject* object)) { 1460c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org SharedFunctionInfo* shared = SharedFunctionInfo::cast(object); 1461c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org shared->BeforeVisitingPointers(); 1462c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 1463c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org 1464ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org static void VisitWeakCollection(Map* map, HeapObject* object) { 1465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); 1466ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSWeakCollection* weak_collection = 1467ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org reinterpret_cast<JSWeakCollection*>(object); 14687c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 14697c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // Enqueue weak map in linked list of encountered weak maps. 1470ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (weak_collection->next() == Smi::FromInt(0)) { 1471ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org weak_collection->set_next(collector->encountered_weak_collections()); 1472ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org collector->set_encountered_weak_collections(weak_collection); 1473fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org } 14747c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 14757c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // Skip visiting the backing hash table containing the mappings. 1476ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org int object_size = JSWeakCollection::BodyDescriptor::SizeOf(map, object); 1477b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers( 1478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com map->GetHeap(), 14797c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org object, 1480ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSWeakCollection::BodyDescriptor::kStartOffset, 1481ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSWeakCollection::kTableOffset); 1482b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers( 1483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com map->GetHeap(), 14847c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org object, 1485ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSWeakCollection::kTableOffset + kPointerSize, 14867c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org object_size); 14877c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 14887c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // Mark the backing hash table without pushing it on the marking stack. 1489ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Object* table_object = weak_collection->table(); 1490fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org if (!table_object->IsHashTable()) return; 1491fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org ObjectHashTable* table = ObjectHashTable::cast(table_object); 1492fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org Object** table_slot = 1493ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HeapObject::RawField(weak_collection, JSWeakCollection::kTableOffset); 1494fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org MarkBit table_mark = Marking::MarkBitFrom(table); 1495fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org collector->RecordSlot(table_slot, table_slot, table); 1496fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org if (!table_mark.Get()) collector->SetMark(table, table_mark); 1497fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org // Recording the map slot can be skipped, because maps are not compacted. 14981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org collector->MarkObject(table->map(), Marking::MarkBitFrom(table->map())); 14991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(MarkCompactCollector::IsMarked(table->map())); 15007c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org } 15017c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 1502b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org private: 1503b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org template<int id> 1504b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj); 1505ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 15060b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org // Code flushing support. 15070b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 1508ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org static const int kRegExpCodeThreshold = 5; 1509ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org 1510ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org static void UpdateRegExpCodeAgeAndFlush(Heap* heap, 1511ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org JSRegExp* re, 1512ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org bool is_ascii) { 1513ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // Make sure that the fixed array is in fact initialized on the RegExp. 1514ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // We could potentially trigger a GC when initializing the RegExp. 1515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (HeapObject::cast(re->data())->map()->instance_type() != 1516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FIXED_ARRAY_TYPE) return; 1517ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org 1518ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // Make sure this is a RegExp that actually contains code. 1519b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (re->TypeTag() != JSRegExp::IRREGEXP) return; 1520ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org 1521b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Object* code = re->DataAt(JSRegExp::code_index(is_ascii)); 1522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!code->IsSmi() && 1523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject::cast(code)->map()->instance_type() == CODE_TYPE) { 1524ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // Save a copy that can be reinstated if we need the code again. 1525b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org re->SetDataAt(JSRegExp::saved_code_index(is_ascii), code); 152678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 152778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Saving a copy might create a pointer into compaction candidate 152878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // that was not observed by marker. This might happen if JSRegExp data 152978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // was marked through the compilation cache before marker reached JSRegExp 153078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // object. 153178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org FixedArray* data = FixedArray::cast(re->data()); 153278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org Object** slot = data->data_start() + JSRegExp::saved_code_index(is_ascii); 153378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org heap->mark_compact_collector()-> 153478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org RecordSlot(slot, slot, code); 153578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 1536ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // Set a number in the 0-255 range to guarantee no smi overflow. 1537b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org re->SetDataAt(JSRegExp::code_index(is_ascii), 1538b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Smi::FromInt(heap->sweep_generation() & 0xff)); 1539ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } else if (code->IsSmi()) { 1540ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org int value = Smi::cast(code)->value(); 1541ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // The regexp has not been compiled yet or there was a compilation error. 1542ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org if (value == JSRegExp::kUninitializedValue || 1543ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org value == JSRegExp::kCompilationErrorValue) { 1544ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org return; 1545ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 1546ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org 1547ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // Check if we should flush now. 1548ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org if (value == ((heap->sweep_generation() - kRegExpCodeThreshold) & 0xff)) { 1549b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org re->SetDataAt(JSRegExp::code_index(is_ascii), 1550b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Smi::FromInt(JSRegExp::kUninitializedValue)); 1551b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org re->SetDataAt(JSRegExp::saved_code_index(is_ascii), 1552b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Smi::FromInt(JSRegExp::kUninitializedValue)); 1553ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 1554ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 1555ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 1556ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org 1557ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org 1558ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // Works by setting the current sweep_generation (as a smi) in the 1559ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // code object place in the data array of the RegExp and keeps a copy 1560ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // around that can be reinstated if we reuse the RegExp before flushing. 1561ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // If we did not use the code for kRegExpCodeThreshold mark sweep GCs 1562ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // we flush the code. 1563ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org static void VisitRegExpAndFlushCode(Map* map, HeapObject* object) { 1564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Heap* heap = map->GetHeap(); 1565ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org MarkCompactCollector* collector = heap->mark_compact_collector(); 1566ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org if (!collector->is_code_flushing_enabled()) { 1567b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org VisitJSRegExp(map, object); 1568ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org return; 1569ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 1570ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org JSRegExp* re = reinterpret_cast<JSRegExp*>(object); 15712efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Flush code or set age on both ASCII and two byte code. 1572ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org UpdateRegExpCodeAgeAndFlush(heap, re, true); 1573ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org UpdateRegExpCodeAgeAndFlush(heap, re, false); 1574ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org // Visit the fields of the RegExp, including the updated FixedArray. 1575b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org VisitJSRegExp(map, object); 1576ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org } 1577ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org 157828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org static VisitorDispatchTable<Callback> non_count_table_; 1579ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org}; 1580ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 1581ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 1582b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgvoid MarkCompactMarkingVisitor::ObjectStatsCountFixedArray( 1583304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FixedArrayBase* fixed_array, 1584304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FixedArraySubInstanceType fast_type, 1585304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FixedArraySubInstanceType dictionary_type) { 1586304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Heap* heap = fixed_array->map()->GetHeap(); 1587304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (fixed_array->map() != heap->fixed_cow_array_map() && 1588304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org fixed_array->map() != heap->fixed_double_array_map() && 1589304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org fixed_array != heap->empty_fixed_array()) { 1590304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (fixed_array->IsDictionary()) { 1591304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org heap->RecordObjectStats(FIXED_ARRAY_TYPE, 1592304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org dictionary_type, 1593304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org fixed_array->Size()); 1594304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } else { 1595304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org heap->RecordObjectStats(FIXED_ARRAY_TYPE, 1596304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org fast_type, 1597304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org fixed_array->Size()); 1598304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1599304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1600304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org} 1601304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1602304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1603b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgvoid MarkCompactMarkingVisitor::ObjectStatsVisitBase( 1604b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkCompactMarkingVisitor::VisitorId id, Map* map, HeapObject* obj) { 1605753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org Heap* heap = map->GetHeap(); 1606753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org int object_size = obj->Size(); 1607753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org heap->RecordObjectStats(map->instance_type(), -1, object_size); 1608304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org non_count_table_.GetVisitorById(id)(map, obj); 1609304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (obj->IsJSObject()) { 1610304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org JSObject* object = JSObject::cast(obj); 1611304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org ObjectStatsCountFixedArray(object->elements(), 1612304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org DICTIONARY_ELEMENTS_SUB_TYPE, 1613304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FAST_ELEMENTS_SUB_TYPE); 1614304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org ObjectStatsCountFixedArray(object->properties(), 1615304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org DICTIONARY_PROPERTIES_SUB_TYPE, 1616304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FAST_PROPERTIES_SUB_TYPE); 1617304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1618304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org} 1619304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1620304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1621b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgtemplate<MarkCompactMarkingVisitor::VisitorId id> 1622b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgvoid MarkCompactMarkingVisitor::ObjectStatsTracker<id>::Visit( 1623304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Map* map, HeapObject* obj) { 1624304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org ObjectStatsVisitBase(id, map, obj); 1625753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org} 1626753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 1627753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 1628753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.orgtemplate<> 1629b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor::ObjectStatsTracker< 1630b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkCompactMarkingVisitor::kVisitMap> { 1631304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org public: 1632304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org static inline void Visit(Map* map, HeapObject* obj) { 1633304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Heap* heap = map->GetHeap(); 1634304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Map* map_obj = Map::cast(obj); 1635304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org ASSERT(map->instance_type() == MAP_TYPE); 1636304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org DescriptorArray* array = map_obj->instance_descriptors(); 163706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org if (map_obj->owns_descriptors() && 163806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org array != heap->empty_descriptor_array()) { 1639304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org int fixed_array_size = array->Size(); 1640304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org heap->RecordObjectStats(FIXED_ARRAY_TYPE, 1641304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org DESCRIPTOR_ARRAY_SUB_TYPE, 1642304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org fixed_array_size); 1643304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1644304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (map_obj->HasTransitionArray()) { 1645304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org int fixed_array_size = map_obj->transitions()->Size(); 1646304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org heap->RecordObjectStats(FIXED_ARRAY_TYPE, 1647304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org TRANSITION_ARRAY_SUB_TYPE, 1648304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org fixed_array_size); 1649304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1650ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (map_obj->has_code_cache()) { 1651ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CodeCache* cache = CodeCache::cast(map_obj->code_cache()); 1652304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org heap->RecordObjectStats( 1653304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FIXED_ARRAY_TYPE, 1654304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org MAP_CODE_CACHE_SUB_TYPE, 1655ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org cache->default_cache()->Size()); 1656ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (!cache->normal_type_cache()->IsUndefined()) { 1657ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org heap->RecordObjectStats( 1658ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org FIXED_ARRAY_TYPE, 1659ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org MAP_CODE_CACHE_SUB_TYPE, 1660ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org FixedArray::cast(cache->normal_type_cache())->Size()); 1661ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 1662304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1663304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org ObjectStatsVisitBase(kVisitMap, map, obj); 1664304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1665304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org}; 1666304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1667304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1668304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.orgtemplate<> 1669b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor::ObjectStatsTracker< 1670b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkCompactMarkingVisitor::kVisitCode> { 1671753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org public: 1672753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org static inline void Visit(Map* map, HeapObject* obj) { 1673753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org Heap* heap = map->GetHeap(); 1674753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org int object_size = obj->Size(); 1675753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org ASSERT(map->instance_type() == CODE_TYPE); 1676753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org heap->RecordObjectStats(CODE_TYPE, Code::cast(obj)->kind(), object_size); 1677304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org ObjectStatsVisitBase(kVisitCode, map, obj); 1678304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1679304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org}; 1680304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1681304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1682304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.orgtemplate<> 1683b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor::ObjectStatsTracker< 1684b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkCompactMarkingVisitor::kVisitSharedFunctionInfo> { 1685304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org public: 1686304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org static inline void Visit(Map* map, HeapObject* obj) { 1687304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Heap* heap = map->GetHeap(); 1688304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); 1689304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org if (sfi->scope_info() != heap->empty_fixed_array()) { 1690304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org heap->RecordObjectStats( 1691304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FIXED_ARRAY_TYPE, 1692304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org SCOPE_INFO_SUB_TYPE, 1693304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FixedArray::cast(sfi->scope_info())->Size()); 1694304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1695304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org ObjectStatsVisitBase(kVisitSharedFunctionInfo, map, obj); 1696304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1697304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org}; 1698304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1699304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1700304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.orgtemplate<> 1701b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor::ObjectStatsTracker< 1702b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkCompactMarkingVisitor::kVisitFixedArray> { 1703304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org public: 1704304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org static inline void Visit(Map* map, HeapObject* obj) { 1705304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Heap* heap = map->GetHeap(); 1706304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FixedArray* fixed_array = FixedArray::cast(obj); 17074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (fixed_array == heap->string_table()) { 1708304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org heap->RecordObjectStats( 1709304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org FIXED_ARRAY_TYPE, 17104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org STRING_TABLE_SUB_TYPE, 1711304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org fixed_array->Size()); 1712304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 1713304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org ObjectStatsVisitBase(kVisitFixedArray, map, obj); 1714753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org } 1715753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org}; 1716753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 1717753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 1718b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgvoid MarkCompactMarkingVisitor::Initialize() { 1719b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); 1720753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 1721753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org table_.Register(kVisitJSRegExp, 1722753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org &VisitRegExpAndFlushCode); 1723753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 1724753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org if (FLAG_track_gc_object_stats) { 1725753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org // Copy the visitor table to make call-through possible. 1726753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org non_count_table_.CopyFrom(&table_); 1727753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#define VISITOR_ID_COUNT_FUNCTION(id) \ 1728753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org table_.Register(kVisit##id, ObjectStatsTracker<kVisit##id>::Visit); 1729753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org VISITOR_ID_LIST(VISITOR_ID_COUNT_FUNCTION) 1730753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#undef VISITOR_ID_COUNT_FUNCTION 1731753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org } 1732753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org} 1733753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 1734753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org 1735b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgVisitorDispatchTable<MarkCompactMarkingVisitor::Callback> 1736b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkCompactMarkingVisitor::non_count_table_; 1737ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 1738ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 17390b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgclass CodeMarkingVisitor : public ThreadVisitor { 17400b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org public: 1741ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org explicit CodeMarkingVisitor(MarkCompactCollector* collector) 1742ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : collector_(collector) {} 1743ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 174474f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 174564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org collector_->PrepareThreadForCodeFlushing(isolate, top); 17460b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 1747ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1748ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org private: 1749ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org MarkCompactCollector* collector_; 17500b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org}; 17510b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 17520b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 17530b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgclass SharedFunctionInfoMarkingVisitor : public ObjectVisitor { 17540b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org public: 1755ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) 1756ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : collector_(collector) {} 1757ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 17582ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org void VisitPointers(Object** start, Object** end) { 17592ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org for (Object** p = start; p < end; p++) VisitPointer(p); 17600b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 17610b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 17620b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org void VisitPointer(Object** slot) { 17630b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org Object* obj = *slot; 1764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (obj->IsSharedFunctionInfo()) { 1765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); 1766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit shared_mark = Marking::MarkBitFrom(shared); 176764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MarkBit code_mark = Marking::MarkBitFrom(shared->code()); 176864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org collector_->MarkObject(shared->code(), code_mark); 1769c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com collector_->MarkObject(shared, shared_mark); 17700b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 17710b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 1772ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1773ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org private: 1774ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org MarkCompactCollector* collector_; 17750b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org}; 17760b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 17770b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 177864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate, 177964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ThreadLocalTop* top) { 178064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { 178164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Note: for the frame that has a pending lazy deoptimization 178264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // StackFrame::unchecked_code will return a non-optimized code object for 178364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // the outermost function and StackFrame::LookupCode will return 178464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // actual optimized code object. 178564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org StackFrame* frame = it.frame(); 178664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Code* code = frame->unchecked_code(); 178764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MarkBit code_mark = Marking::MarkBitFrom(code); 178864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org MarkObject(code, code_mark); 178964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (frame->is_optimized()) { 1790c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org MarkCompactMarkingVisitor::MarkInlinedFunctionsCode(heap(), 1791c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org frame->LookupCode()); 179264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 179364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 179464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 179564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 179664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 17970b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid MarkCompactCollector::PrepareForCodeFlushing() { 1798c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(heap() == Isolate::Current()->heap()); 1799ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1800e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // Enable code flushing for non-incremental cycles. 1801e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (FLAG_flush_code && !FLAG_flush_code_incrementally) { 1802e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org EnableCodeFlushing(!was_marked_incrementally_); 1803b101611b084c6b9ec7f7e5f174d40183dd665f2cmstarzinger@chromium.org } 1804b101611b084c6b9ec7f7e5f174d40183dd665f2cmstarzinger@chromium.org 1805e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // If code flushing is disabled, there is no need to prepare for it. 1806e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (!is_code_flushing_enabled()) return; 18070b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 18085b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // Ensure that empty descriptor array is marked. Method MarkDescriptorArray 18095b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // relies on it being marked before any other descriptor array. 1810c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* descriptor_array = heap()->empty_descriptor_array(); 1811c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit descriptor_array_mark = Marking::MarkBitFrom(descriptor_array); 1812c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkObject(descriptor_array, descriptor_array_mark); 18135b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 18140b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org // Make sure we are not referencing the code from the stack. 1815c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(this == heap()->mark_compact_collector()); 181664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org PrepareThreadForCodeFlushing(heap()->isolate(), 181764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org heap()->isolate()->thread_local_top()); 18180b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 18190b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org // Iterate the archived stacks in all threads to check if 18200b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org // the code is referenced. 1821ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CodeMarkingVisitor code_marking_visitor(this); 1822c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->isolate()->thread_manager()->IterateArchivedThreads( 1823ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org &code_marking_visitor); 18240b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 1825ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org SharedFunctionInfoMarkingVisitor visitor(this); 1826c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->isolate()->compilation_cache()->IterateFunctions(&visitor); 1827c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->isolate()->handle_scope_implementer()->Iterate(&visitor); 18280b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 1829c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ProcessMarkingDeque(); 18300b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org} 18310b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 18320b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 183331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Visitor class for marking heap roots. 183431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.agerclass RootMarkingVisitor : public ObjectVisitor { 183531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager public: 1836ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org explicit RootMarkingVisitor(Heap* heap) 1837ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : collector_(heap->mark_compact_collector()) { } 1838ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 183931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager void VisitPointer(Object** p) { 184031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager MarkObjectByPointer(p); 184131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager } 184231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 18432ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org void VisitPointers(Object** start, Object** end) { 18442ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org for (Object** p = start; p < end; p++) MarkObjectByPointer(p); 184531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager } 184631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 184731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager private: 184831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager void MarkObjectByPointer(Object** p) { 184931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager if (!(*p)->IsHeapObject()) return; 185031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 185131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // Replace flat cons strings in place. 185231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager HeapObject* object = ShortCircuitConsString(p); 1853c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark_bit = Marking::MarkBitFrom(object); 1854c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mark_bit.Get()) return; 185531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 185631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager Map* map = object->map(); 185731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // Mark the object. 1858c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com collector_->SetMark(object, mark_bit); 1859ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 186031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // Mark the map pointer and body, and push them on the marking stack. 1861c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit map_mark = Marking::MarkBitFrom(map); 1862c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com collector_->MarkObject(map, map_mark); 1863b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkCompactMarkingVisitor::IterateBody(map, object); 186431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 186531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // Mark all the objects reachable from the map and body. May leave 186631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager // overflowed objects in the heap. 1867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com collector_->EmptyMarkingDeque(); 186831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager } 1869ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1870ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org MarkCompactCollector* collector_; 187131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager}; 187231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 187331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 18744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org// Helper class for pruning the string table. 18754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgclass StringTableCleaner : public ObjectVisitor { 187643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 18774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org explicit StringTableCleaner(Heap* heap) 1878c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : heap_(heap), pointers_removed_(0) { } 187913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 18802ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org virtual void VisitPointers(Object** start, Object** end) { 18812ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org // Visit all HeapObject pointers in [start, end). 18822ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org for (Object** p = start; p < end; p++) { 1883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object* o = *p; 1884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (o->IsHeapObject() && 1885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !Marking::MarkBitFrom(HeapObject::cast(o)).Get()) { 18864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Check if the internalized string being pruned is external. We need to 18874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // delete the associated external data as this string is going away. 18886f10e41fef1524c70846d970268de222e41c594cager@chromium.org 18896f10e41fef1524c70846d970268de222e41c594cager@chromium.org // Since no objects have yet been moved we can safely access the map of 18906f10e41fef1524c70846d970268de222e41c594cager@chromium.org // the object. 1891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (o->IsExternalString()) { 1892c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap_->FinalizeExternalString(String::cast(*p)); 18936f10e41fef1524c70846d970268de222e41c594cager@chromium.org } 1894c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Set the entry to the_hole_value (as deleted). 1895c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org *p = heap_->the_hole_value(); 189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen pointers_removed_++; 189743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 189943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 190043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 190143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int PointersRemoved() { 190243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return pointers_removed_; 190343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1904e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 190543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 1906c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Heap* heap_; 190743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int pointers_removed_; 190843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 190943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 191043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19114a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org// Implementation of WeakObjectRetainer for mark compact GCs. All marked objects 19124a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org// are retained. 19134a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgclass MarkCompactWeakObjectRetainer : public WeakObjectRetainer { 19144a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org public: 19154a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org virtual Object* RetainAs(Object* object) { 1916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (Marking::MarkBitFrom(HeapObject::cast(object)).Get()) { 19174a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org return object; 19184a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org } else { 19194a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org return NULL; 19204a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org } 19214a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org } 19224a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org}; 19234a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 19244a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 1925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Fill the marking stack with overflowed objects returned by the given 1926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// iterator. Stop when the marking stack is filled or the end of the space 1927c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// is reached, whichever comes first. 1928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comtemplate<class T> 1929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void DiscoverGreyObjectsWithIterator(Heap* heap, 1930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkingDeque* marking_deque, 1931c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com T* it) { 1932c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The caller should ensure that the marking stack is initially not full, 1933c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // so that we don't waste effort pointlessly scanning for objects. 1934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!marking_deque->IsFull()); 193543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Map* filler_map = heap->one_pointer_filler_map(); 1937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (HeapObject* object = it->Next(); 1938c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object != NULL; 1939c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object = it->Next()) { 1940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit markbit = Marking::MarkBitFrom(object); 1941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((object->map() != filler_map) && Marking::IsGrey(markbit)) { 1942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Marking::GreyToBlack(markbit); 19432efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); 1944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com marking_deque->PushBlack(object); 1945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque->IsFull()) return; 194643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 194743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1948c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 194943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 195043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts); 195243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 195343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1954bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgstatic void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, 1955bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org MemoryChunk* p) { 19562c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org ASSERT(!marking_deque->IsFull()); 1957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); 1958c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 1959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); 1960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 19615ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 196210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { 196310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Address cell_base = it.CurrentCellBase(); 196410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBit::CellType* cell = it.CurrentCell(); 19655ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 196610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org const MarkBit::CellType current_cell = *cell; 1967c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (current_cell == 0) continue; 1968c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 196910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBit::CellType grey_objects; 197010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (it.HasNext()) { 197110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org const MarkBit::CellType next_cell = *(cell+1); 197210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org grey_objects = current_cell & 197310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org ((current_cell >> 1) | (next_cell << (Bitmap::kBitsPerCell - 1))); 197410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } else { 197510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org grey_objects = current_cell & (current_cell >> 1); 197610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 1977c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1978c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset = 0; 1979c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (grey_objects != 0) { 1980c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(grey_objects); 1981c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com grey_objects >>= trailing_zeros; 1982c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com offset += trailing_zeros; 198310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBit markbit(cell, 1 << offset, false); 1984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(Marking::IsGrey(markbit)); 1985c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Marking::GreyToBlack(markbit); 1986c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address addr = cell_base + offset * kPointerSize; 1987c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* object = HeapObject::FromAddress(addr); 19882efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); 1989c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com marking_deque->PushBlack(object); 1990c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque->IsFull()) return; 1991c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com offset += 2; 1992c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com grey_objects >>= 2; 1993c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1994c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1995c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com grey_objects >>= (Bitmap::kBitsPerCell - 1); 1996c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1998c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1999c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2000169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgint MarkCompactCollector::DiscoverAndPromoteBlackObjectsOnPage( 2001169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org NewSpace* new_space, 2002169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org NewSpacePage* p) { 2003169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); 2004169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 2005169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); 2006169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 2007169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 2008169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org MarkBit::CellType* cells = p->markbits()->cells(); 2009169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int survivors_size = 0; 2010169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 201110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { 201210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Address cell_base = it.CurrentCellBase(); 201310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBit::CellType* cell = it.CurrentCell(); 201410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 201510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBit::CellType current_cell = *cell; 2016169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (current_cell == 0) continue; 2017169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 2018169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int offset = 0; 2019169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org while (current_cell != 0) { 2020169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(current_cell); 2021169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org current_cell >>= trailing_zeros; 2022169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org offset += trailing_zeros; 2023169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Address address = cell_base + offset * kPointerSize; 2024169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org HeapObject* object = HeapObject::FromAddress(address); 2025169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 2026169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org int size = object->Size(); 2027169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org survivors_size += size; 2028169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 2029169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org offset++; 2030169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org current_cell >>= 1; 2031169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Aggressively promote young survivors to the old space. 2032169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (TryPromoteObject(object, size)) { 2033169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org continue; 2034169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 2035169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 2036169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Promotion failed. Just migrate object to another semispace. 2037169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org MaybeObject* allocation = new_space->AllocateRaw(size); 2038169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (allocation->IsFailure()) { 2039169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org if (!new_space->AddFreshPage()) { 2040169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // Shouldn't happen. We are sweeping linearly, and to-space 2041169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // has the same number of pages as from-space, so there is 2042169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // always room. 2043169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org UNREACHABLE(); 2044169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 2045169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org allocation = new_space->AllocateRaw(size); 2046169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org ASSERT(!allocation->IsFailure()); 2047169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 2048169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org Object* target = allocation->ToObjectUnchecked(); 2049169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 2050169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org MigrateObject(HeapObject::cast(target)->address(), 2051169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org object->address(), 2052169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org size, 2053169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org NEW_SPACE); 2054169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 205510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org *cells = 0; 2056169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } 2057169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org return survivors_size; 2058169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org} 2059169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 2060169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org 2061c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void DiscoverGreyObjectsInSpace(Heap* heap, 2062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkingDeque* marking_deque, 2063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PagedSpace* space) { 2064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!space->was_swept_conservatively()) { 2065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObjectIterator it(space); 2066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DiscoverGreyObjectsWithIterator(heap, marking_deque, &it); 2067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PageIterator it(space); 2069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 2070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = it.next(); 2071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DiscoverGreyObjectsOnPage(marking_deque, p); 2072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque->IsFull()) return; 2073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2076c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2078bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgstatic void DiscoverGreyObjectsInNewSpace(Heap* heap, 2079bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org MarkingDeque* marking_deque) { 2080bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org NewSpace* space = heap->new_space(); 2081bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org NewSpacePageIterator it(space->bottom(), space->top()); 2082bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org while (it.has_next()) { 2083bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org NewSpacePage* page = it.next(); 2084bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org DiscoverGreyObjectsOnPage(marking_deque, page); 2085bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (marking_deque->IsFull()) return; 2086bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 2087bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 2088bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 2089bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 2090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 2091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object* o = *p; 2092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!o->IsHeapObject()) return false; 2093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* heap_object = HeapObject::cast(o); 2094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark = Marking::MarkBitFrom(heap_object); 2095c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return !mark.Get(); 2096c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2097c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 209949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgbool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap, 210049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org Object** p) { 210149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org Object* o = *p; 210249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org ASSERT(o->IsHeapObject()); 210349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org HeapObject* heap_object = HeapObject::cast(o); 210449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org MarkBit mark = Marking::MarkBitFrom(heap_object); 210549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org return !mark.Get(); 210649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org} 210749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org 210849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org 21091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) { 21104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org StringTable* string_table = heap()->string_table(); 21114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Mark the string table itself. 21124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org MarkBit string_table_mark = Marking::MarkBitFrom(string_table); 21134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org SetMark(string_table, string_table_mark); 2114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Explicitly mark the prefix. 21151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org string_table->IteratePrefix(visitor); 2116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ProcessMarkingDeque(); 2117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { 2121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Mark the heap roots including global variables, stack variables, 2122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // etc., and all objects reachable from them. 2123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); 2124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 21254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Handle the string table specially. 21261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org MarkStringTable(visitor); 2127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // There may be overflowed objects in the heap. Visit them now. 2129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (marking_deque_.overflowed()) { 2130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RefillMarkingDeque(); 2131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EmptyMarkingDeque(); 2132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 21337276f14ca716596e0a0d17539516370c1f453847kasper.lund} 21347276f14ca716596e0a0d17539516370c1f453847kasper.lund 21357276f14ca716596e0a0d17539516370c1f453847kasper.lund 2136badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MarkCompactCollector::MarkImplicitRefGroups() { 2137ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org List<ImplicitRefGroup*>* ref_groups = 2138876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org isolate()->global_handles()->implicit_ref_groups(); 2139badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 214044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org int last = 0; 2141badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org for (int i = 0; i < ref_groups->length(); i++) { 2142badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org ImplicitRefGroup* entry = ref_groups->at(i); 214344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ASSERT(entry != NULL); 2144badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 2145ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (!IsMarked(*entry->parent)) { 214644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org (*ref_groups)[last++] = entry; 214744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org continue; 214844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 2149badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 2150ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Object*** children = entry->children; 215144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // A parent object is marked, so mark all child heap objects. 2152ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org for (size_t j = 0; j < entry->length; ++j) { 2153badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if ((*children[j])->IsHeapObject()) { 2154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* child = HeapObject::cast(*children[j]); 2155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark = Marking::MarkBitFrom(child); 2156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkObject(child, mark); 2157badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 2158badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 2159badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 216044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // Once the entire group has been marked, dispose it because it's 216144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // not needed anymore. 2162ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org delete entry; 2163badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 216444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ref_groups->Rewind(last); 2165badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 2166badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 2167badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 216831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Mark all objects reachable from the objects on the marking stack. 216931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Before: the marking stack contains zero or more heap object pointers. 217031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// After: the marking stack is empty, and all objects reachable from the 217131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// marking stack have been marked, or are overflowed in the heap. 2172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EmptyMarkingDeque() { 2173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (!marking_deque_.IsEmpty()) { 2174d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org HeapObject* object = marking_deque_.Pop(); 2175d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org ASSERT(object->IsHeapObject()); 2176d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org ASSERT(heap()->Contains(object)); 2177d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); 21787c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 2179d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org Map* map = object->map(); 2180d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org MarkBit map_mark = Marking::MarkBitFrom(map); 2181d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org MarkObject(map, map_mark); 2182ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 2183d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org MarkCompactMarkingVisitor::IterateBody(map, object); 218431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager } 218531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager} 218631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 218743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 218831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Sweep the heap for overflowed objects, clear their overflow bits, and 218931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// push them on the marking stack. Stop early if the marking stack fills 219031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// before sweeping completes. If sweeping completes, there are no remaining 219131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// overflowed objects in the heap so the overflow flag on the markings stack 219231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// is cleared. 2193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::RefillMarkingDeque() { 2194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(marking_deque_.overflowed()); 219543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2196bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_); 2197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque_.IsFull()) return; 219843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DiscoverGreyObjectsInSpace(heap(), 2200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &marking_deque_, 2201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->old_pointer_space()); 2202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque_.IsFull()) return; 22039258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 2204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DiscoverGreyObjectsInSpace(heap(), 2205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &marking_deque_, 2206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->old_data_space()); 2207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque_.IsFull()) return; 220843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DiscoverGreyObjectsInSpace(heap(), 2210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &marking_deque_, 2211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->code_space()); 2212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque_.IsFull()) return; 221343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DiscoverGreyObjectsInSpace(heap(), 2215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &marking_deque_, 2216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->map_space()); 2217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque_.IsFull()) return; 221843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DiscoverGreyObjectsInSpace(heap(), 2220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &marking_deque_, 2221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->cell_space()); 2222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque_.IsFull()) return; 2223defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 222441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org DiscoverGreyObjectsInSpace(heap(), 222541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org &marking_deque_, 222641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org heap()->property_cell_space()); 222741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (marking_deque_.IsFull()) return; 222841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 2229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LargeObjectIterator lo_it(heap()->lo_space()); 2230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DiscoverGreyObjectsWithIterator(heap(), 2231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &marking_deque_, 2232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &lo_it); 2233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (marking_deque_.IsFull()) return; 223431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 2235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com marking_deque_.ClearOverflowed(); 223631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager} 223731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 223831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 223931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Mark all objects reachable (transitively) from objects on the marking 224031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// stack. Before: the marking stack contains zero or more heap object 224131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// pointers. After: the marking stack is empty and there are no overflowed 224231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// objects in the heap. 2243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::ProcessMarkingDeque() { 2244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EmptyMarkingDeque(); 2245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (marking_deque_.overflowed()) { 2246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RefillMarkingDeque(); 2247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EmptyMarkingDeque(); 224843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 22497276f14ca716596e0a0d17539516370c1f453847kasper.lund} 22507276f14ca716596e0a0d17539516370c1f453847kasper.lund 22517276f14ca716596e0a0d17539516370c1f453847kasper.lund 2252d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org// Mark all objects reachable (transitively) from objects on the marking 2253d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org// stack including references only considered in the atomic marking pause. 2254d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgvoid MarkCompactCollector::ProcessEphemeralMarking(ObjectVisitor* visitor) { 22557276f14ca716596e0a0d17539516370c1f453847kasper.lund bool work_to_do = true; 2256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(marking_deque_.IsEmpty()); 22577276f14ca716596e0a0d17539516370c1f453847kasper.lund while (work_to_do) { 2258876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org isolate()->global_handles()->IterateObjectGroups( 225949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org visitor, &IsUnmarkedHeapObjectWithHeap); 2260badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org MarkImplicitRefGroups(); 2261ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ProcessWeakCollections(); 2262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com work_to_do = !marking_deque_.IsEmpty(); 2263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ProcessMarkingDeque(); 22647276f14ca716596e0a0d17539516370c1f453847kasper.lund } 22657276f14ca716596e0a0d17539516370c1f453847kasper.lund} 22667276f14ca716596e0a0d17539516370c1f453847kasper.lund 22677276f14ca716596e0a0d17539516370c1f453847kasper.lund 2268c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) { 2269c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org for (StackFrameIterator it(isolate(), isolate()->thread_local_top()); 2270c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org !it.done(); it.Advance()) { 2271c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (it.frame()->type() == StackFrame::JAVA_SCRIPT) { 2272c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org return; 2273c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 2274c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (it.frame()->type() == StackFrame::OPTIMIZED) { 2275c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Code* code = it.frame()->LookupCode(); 2276c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (!code->CanDeoptAt(it.frame()->pc())) { 2277c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org code->CodeIterateBody(visitor); 2278c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 2279c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org ProcessMarkingDeque(); 2280c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org return; 2281c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 2282c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 2283c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 2284c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 2285c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 22867276f14ca716596e0a0d17539516370c1f453847kasper.lundvoid MarkCompactCollector::MarkLiveObjects() { 22879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); 22885f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // The recursive GC marker detects when it is nearing stack overflow, 22895f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // and switches to a different marking system. JS interrupts interfere 22905f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // with the C stack limit check. 2291876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org PostponeInterruptsScope postpone(isolate()); 22925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 2293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool incremental_marking_overflowed = false; 2294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com IncrementalMarking* incremental_marking = heap_->incremental_marking(); 2295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (was_marked_incrementally_) { 2296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Finalize the incremental marking and check whether we had an overflow. 2297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Both markers use grey color to mark overflowed objects so 2298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // non-incremental marker can deal with them as if overflow 2299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // occured during normal marking. 2300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // But incremental marker uses a separate marking deque 230156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // so we have to explicitly copy its overflow state. 2302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com incremental_marking->Finalize(); 2303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com incremental_marking_overflowed = 2304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com incremental_marking->marking_deque()->overflowed(); 2305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com incremental_marking->marking_deque()->ClearOverflowed(); 2306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Abort any pending incremental activities e.g. incremental sweeping. 2308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com incremental_marking->Abort(); 2309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 23117276f14ca716596e0a0d17539516370c1f453847kasper.lund#ifdef DEBUG 23127276f14ca716596e0a0d17539516370c1f453847kasper.lund ASSERT(state_ == PREPARE_GC); 23137276f14ca716596e0a0d17539516370c1f453847kasper.lund state_ = MARK_LIVE_OBJECTS; 23147276f14ca716596e0a0d17539516370c1f453847kasper.lund#endif 2315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The to space contains live objects, a page in from space is used as a 2316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // marking stack. 2317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address marking_deque_start = heap()->new_space()->FromSpacePageLow(); 2318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address marking_deque_end = heap()->new_space()->FromSpacePageHigh(); 2319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_force_marking_deque_overflows) { 2320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com marking_deque_end = marking_deque_start + 64 * kPointerSize; 2321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com marking_deque_.Initialize(marking_deque_start, 2323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com marking_deque_end); 2324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!marking_deque_.overflowed()); 23257276f14ca716596e0a0d17539516370c1f453847kasper.lund 2326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (incremental_marking_overflowed) { 2327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // There are overflowed objects left in the heap after incremental marking. 2328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com marking_deque_.SetOverflowed(); 2329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 233043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23310b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org PrepareForCodeFlushing(); 23320b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 233364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (was_marked_incrementally_) { 233464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // There is no write barrier on cells so we have to scan them now at the end 233564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // of the incremental marking. 233664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org { 233764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org HeapObjectIterator cell_iterator(heap()->cell_space()); 233864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org HeapObject* cell; 233964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org while ((cell = cell_iterator.Next()) != NULL) { 234041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ASSERT(cell->IsCell()); 234141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (IsMarked(cell)) { 234241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org int offset = Cell::kValueOffset; 234341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org MarkCompactMarkingVisitor::VisitPointer( 234441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org heap(), 234541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org reinterpret_cast<Object**>(cell->address() + offset)); 234641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 234741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 234841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 234941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org { 235041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org HeapObjectIterator js_global_property_cell_iterator( 235141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org heap()->property_cell_space()); 235241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org HeapObject* cell; 235341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org while ((cell = js_global_property_cell_iterator.Next()) != NULL) { 2354b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ASSERT(cell->IsPropertyCell()); 235564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (IsMarked(cell)) { 23561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org MarkCompactMarkingVisitor::VisitPropertyCell(cell->map(), cell); 235764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 235864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 235964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 236064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 236164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 2362c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org RootMarkingVisitor root_visitor(heap()); 23635ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org MarkRoots(&root_visitor); 23647276f14ca716596e0a0d17539516370c1f453847kasper.lund 2365c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org ProcessTopOptimizedFrame(&root_visitor); 2366c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 23679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // The objects reachable from the roots are marked, yet unreachable 2368badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // objects are unmarked. Mark objects reachable due to host 2369d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // application specific logic or through Harmony weak maps. 2370d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org ProcessEphemeralMarking(&root_visitor); 23717276f14ca716596e0a0d17539516370c1f453847kasper.lund 2372d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // The objects reachable from the roots, weak maps or object groups 2373d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // are marked, yet unreachable objects are unmarked. Mark objects 2374d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // reachable only from weak global handles. 23757276f14ca716596e0a0d17539516370c1f453847kasper.lund // 23769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // First we identify nonlive weak handles and mark them as pending 23779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // destruction. 2378c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->isolate()->global_handles()->IdentifyWeakHandles( 2379ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org &IsUnmarkedHeapObject); 23809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Then we mark the objects and process the transitive closure. 2381c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor); 2382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (marking_deque_.overflowed()) { 2383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RefillMarkingDeque(); 2384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EmptyMarkingDeque(); 238531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager } 23867276f14ca716596e0a0d17539516370c1f453847kasper.lund 2387d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // Repeat host application specific and Harmony weak maps marking to 2388d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org // mark unmarked objects reachable from the weak roots. 2389d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org ProcessEphemeralMarking(&root_visitor); 23907276f14ca716596e0a0d17539516370c1f453847kasper.lund 2391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AfterMarking(); 2392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::AfterMarking() { 23964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Object literal map caches reference strings (cache keys) and maps 23974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // (cache values). At this point still useful maps have already been 23984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // marked. Mark the keys for the alive values before we process the 23994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // string table. 24004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ProcessMapCaches(); 24014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 24024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Prune the string table removing all strings only pointed to by the 24034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // string table. Cannot use string_table() here because the string 24047276f14ca716596e0a0d17539516370c1f453847kasper.lund // table is marked. 24054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org StringTable* string_table = heap()->string_table(); 24064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org StringTableCleaner v(heap()); 24074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org string_table->IterateElements(&v); 24084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org string_table->ElementsRemoved(v.PointersRemoved()); 2409c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->external_string_table_.Iterate(&v); 2410c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->external_string_table_.CleanUp(); 241143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24124a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // Process the weak references. 24134a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org MarkCompactWeakObjectRetainer mark_compact_object_retainer; 2414c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->ProcessWeakReferences(&mark_compact_object_retainer); 24154a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 241643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Remove object groups after marking phase. 2417c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->isolate()->global_handles()->RemoveObjectGroups(); 2418c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org heap()->isolate()->global_handles()->RemoveImplicitRefGroups(); 2419a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Flush code from collected candidates. 2421ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (is_code_flushing_enabled()) { 2422ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org code_flusher_->ProcessCandidates(); 2423e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // If incremental marker does not support code flushing, we need to 2424e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org // disable it before incremental marking steps for next cycle. 2425e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org if (FLAG_flush_code && !FLAG_flush_code_incrementally) { 2426e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org EnableCodeFlushing(false); 2427e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 2428ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 24299ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 243078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (!FLAG_watch_ic_patching) { 243178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Clean up dead objects from the runtime profiler. 243278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org heap()->isolate()->runtime_profiler()->RemoveDeadSamples(); 243378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 243428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org 243528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org if (FLAG_track_gc_object_stats) { 243628583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org heap()->CheckpointObjectStats(); 243728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org } 243843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 243943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 244043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgvoid MarkCompactCollector::ProcessMapCaches() { 244246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Object* raw_context = heap()->native_contexts_list_; 24434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org while (raw_context != heap()->undefined_value()) { 24444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Context* context = reinterpret_cast<Context*>(raw_context); 2445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (IsMarked(context)) { 24464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HeapObject* raw_map_cache = 24474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org HeapObject::cast(context->get(Context::MAP_CACHE_INDEX)); 24484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // A map cache may be reachable from the stack. In this case 24494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // it's already transitively marked and it's too late to clean 24504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // up its parts. 2451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!IsMarked(raw_map_cache) && 24524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org raw_map_cache != heap()->undefined_value()) { 24534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MapCache* map_cache = reinterpret_cast<MapCache*>(raw_map_cache); 24544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int existing_elements = map_cache->NumberOfElements(); 24554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int used_elements = 0; 24564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int i = MapCache::kElementsStartIndex; 24574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org i < map_cache->length(); 24584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org i += MapCache::kEntrySize) { 24594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Object* raw_key = map_cache->get(i); 24604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (raw_key == heap()->undefined_value() || 2461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org raw_key == heap()->the_hole_value()) continue; 24624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org STATIC_ASSERT(MapCache::kEntrySize == 2); 24634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Object* raw_map = map_cache->get(i + 1); 2464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (raw_map->IsHeapObject() && IsMarked(raw_map)) { 24654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ++used_elements; 24664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } else { 24674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Delete useless entries with unmarked maps. 24684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(raw_map->IsMap()); 2469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org map_cache->set_the_hole(i); 2470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org map_cache->set_the_hole(i + 1); 24714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 24724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 24734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (used_elements == 0) { 24744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org context->set(Context::MAP_CACHE_INDEX, heap()->undefined_value()); 24754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } else { 24764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Note: we don't actually shrink the cache here to avoid 24774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // extra complexity during GC. We rely on subsequent cache 24784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // usages (EnsureCapacity) to do this. 24794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org map_cache->ElementsRemoved(existing_elements - used_elements); 2480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit map_cache_markbit = Marking::MarkBitFrom(map_cache); 2481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkObject(map_cache, map_cache_markbit); 24824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 24834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 24844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 24854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Move to next element in the list. 24864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org raw_context = context->get(Context::NEXT_CONTEXT_LINK); 24874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ProcessMarkingDeque(); 24894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org} 24904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 24914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2492c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::ReattachInitialMaps() { 2493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObjectIterator map_iterator(heap()->map_space()); 2494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (HeapObject* obj = map_iterator.Next(); 2495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com obj != NULL; 2496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com obj = map_iterator.Next()) { 2497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Map* map = Map::cast(obj); 249843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 2500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (map->instance_type() < FIRST_JS_RECEIVER_TYPE) continue; 250130ce411529579186181838984710b0b0980857aaricow@chromium.org 2502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (map->attached_to_shared_function_info()) { 2503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); 2504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 25069bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org} 25079bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org 250830ce411529579186181838984710b0b0980857aaricow@chromium.org 2509003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgvoid MarkCompactCollector::ClearNonLiveReferences() { 25109bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org // Iterate over the map space, setting map transitions that go from 2511212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // a marked map to an unmarked map to null transitions. This action 2512212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // is carried out only on maps of JSObjects and related subtypes. 25131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HeapObjectIterator map_iterator(heap()->map_space()); 2514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (HeapObject* obj = map_iterator.Next(); 25151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org obj != NULL; 25161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org obj = map_iterator.Next()) { 25171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Map* map = Map::cast(obj); 25189bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org 2519003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (!map->CanTransition()) continue; 25204a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 25211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org MarkBit map_mark = Marking::MarkBitFrom(map); 25221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (map_mark.Get() && map->attached_to_shared_function_info()) { 25234a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // This map is used for inobject slack tracking and has been detached 25244a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // from SharedFunctionInfo during the mark phase. 25254a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Since it survived the GC, reattach it now. 2526b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); 25274a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 25284a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 2529659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ClearNonLivePrototypeTransitions(map); 2530659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org ClearNonLiveMapTransitions(map, map_mark); 2531003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 2532003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (map_mark.Get()) { 25331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ClearNonLiveDependentCode(map->dependent_code()); 2534003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } else { 25352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org ClearAndDeoptimizeDependentCode(map); 2536003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 2537659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 25381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 25391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Iterate over property cell space, removing dependent code that is not 25401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // otherwise kept alive by strong references. 25411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org HeapObjectIterator cell_iterator(heap_->property_cell_space()); 25421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org for (HeapObject* cell = cell_iterator.Next(); 25431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org cell != NULL; 25441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org cell = cell_iterator.Next()) { 25451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (IsMarked(cell)) { 25461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ClearNonLiveDependentCode(PropertyCell::cast(cell)->dependent_code()); 25471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 25481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 2549659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org} 2550659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2551659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2552659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgvoid MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { 2553659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int number_of_transitions = map->NumberOfProtoTransitions(); 255481cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org FixedArray* prototype_transitions = map->GetPrototypeTransitions(); 2555659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2556659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int new_number_of_transitions = 0; 2557659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org const int header = Map::kProtoTransitionHeaderSize; 2558659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org const int proto_offset = header + Map::kProtoTransitionPrototypeOffset; 2559659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org const int map_offset = header + Map::kProtoTransitionMapOffset; 2560659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org const int step = Map::kProtoTransitionElementsPerEntry; 2561659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org for (int i = 0; i < number_of_transitions; i++) { 2562659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Object* prototype = prototype_transitions->get(proto_offset + i * step); 2563659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Object* cached_map = prototype_transitions->get(map_offset + i * step); 2564659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (IsMarked(prototype) && IsMarked(cached_map)) { 2565659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int proto_index = proto_offset + new_number_of_transitions * step; 2566659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int map_index = map_offset + new_number_of_transitions * step; 2567659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (new_number_of_transitions != i) { 2568b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org prototype_transitions->set( 2569659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org proto_index, 2570659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org prototype, 2571659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org UPDATE_WRITE_BARRIER); 2572b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org prototype_transitions->set( 2573659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org map_index, 2574659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org cached_map, 2575659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org SKIP_WRITE_BARRIER); 25763847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com } 2577659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Object** slot = 2578659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org HeapObject::RawField(prototype_transitions, 2579659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org FixedArray::OffsetOfElementAt(proto_index)); 2580659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org RecordSlot(slot, slot, prototype); 2581659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org new_number_of_transitions++; 25822efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 2583659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 25843847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 2585659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org if (new_number_of_transitions != number_of_transitions) { 2586659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org map->SetNumberOfProtoTransitions(new_number_of_transitions); 2587659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 25883847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com 2589659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org // Fill slots that became free with undefined value. 2590659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org for (int i = new_number_of_transitions * step; 2591659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org i < number_of_transitions * step; 2592659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org i++) { 2593659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org prototype_transitions->set_undefined(heap_, header + i); 2594659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org } 2595659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org} 25962efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 2597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2598659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgvoid MarkCompactCollector::ClearNonLiveMapTransitions(Map* map, 2599659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org MarkBit map_mark) { 2600212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org Object* potential_parent = map->GetBackPointer(); 2601212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (!potential_parent->IsMap()) return; 2602212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org Map* parent = Map::cast(potential_parent); 2603659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 2604212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Follow back pointer, check whether we are dealing with a map transition 2605212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // from a live map to a dead path and in case clear transitions of parent. 2606659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org bool current_is_alive = map_mark.Get(); 2607212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org bool parent_is_alive = Marking::MarkBitFrom(parent).Get(); 2608212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (!current_is_alive && parent_is_alive) { 2609212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org parent->ClearNonLiveTransitions(heap()); 26109bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org } 26119bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org} 261243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26137c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 26142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgvoid MarkCompactCollector::ClearAndDeoptimizeDependentCode(Map* map) { 261579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_allocation; 26162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org DependentCode* entries = map->dependent_code(); 26172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org DependentCode::GroupStartIndexes starts(entries); 26182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org int number_of_entries = starts.number_of_entries(); 26192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (number_of_entries == 0) return; 26202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org for (int i = 0; i < number_of_entries; i++) { 262141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // If the entry is compilation info then the map must be alive, 262241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // and ClearAndDeoptimizeDependentCode shouldn't be called. 262341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ASSERT(entries->is_code_at(i)); 26242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org Code* code = entries->code_at(i); 2625fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 2626fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (IsMarked(code) && !WillBeDeoptimized(code)) { 2627fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // Insert the code into the code_to_deoptimize linked list. 2628fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Object* next = code_to_deoptimize_; 2629fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (next != Smi::FromInt(0)) { 2630fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // Record the slot so that it is updated. 2631fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Object** slot = code->code_to_deoptimize_link_slot(); 2632fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org RecordSlot(slot, slot, next); 2633fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 2634fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org code->set_code_to_deoptimize_link(next); 2635fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org code_to_deoptimize_ = code; 2636003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 263741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org entries->clear_at(i); 2638003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 26392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array())); 2640003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org} 2641003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 2642003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 26431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) { 264479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_allocation; 26452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org DependentCode::GroupStartIndexes starts(entries); 26462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org int number_of_entries = starts.number_of_entries(); 26472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (number_of_entries == 0) return; 26482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org int new_number_of_entries = 0; 26492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org // Go through all groups, remove dead codes and compact. 26502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org for (int g = 0; g < DependentCode::kGroupCount; g++) { 26512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org int group_number_of_entries = 0; 26522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org for (int i = starts.at(g); i < starts.at(g + 1); i++) { 265341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Object* obj = entries->object_at(i); 265441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org ASSERT(obj->IsCode() || IsMarked(obj)); 265541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (IsMarked(obj) && 2656fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org (!obj->IsCode() || !WillBeDeoptimized(Code::cast(obj)))) { 26572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (new_number_of_entries + group_number_of_entries != i) { 265841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org entries->set_object_at( 265941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org new_number_of_entries + group_number_of_entries, obj); 26602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 266141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Object** slot = entries->slot_at(new_number_of_entries + 266241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org group_number_of_entries); 266341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org RecordSlot(slot, slot, obj); 26642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org group_number_of_entries++; 2665003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 2666003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 26672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org entries->set_number_of_entries( 26682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org static_cast<DependentCode::DependencyGroup>(g), 26692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org group_number_of_entries); 26702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org new_number_of_entries += group_number_of_entries; 2671003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 26722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org for (int i = new_number_of_entries; i < number_of_entries; i++) { 267341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org entries->clear_at(i); 2674003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 2675003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org} 2676003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 2677003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 2678ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MarkCompactCollector::ProcessWeakCollections() { 2679ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKCOLLECTION_PROCESS); 2680ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Object* weak_collection_obj = encountered_weak_collections(); 2681ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org while (weak_collection_obj != Smi::FromInt(0)) { 2682ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ASSERT(MarkCompactCollector::IsMarked( 2683ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HeapObject::cast(weak_collection_obj))); 2684ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSWeakCollection* weak_collection = 2685ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org reinterpret_cast<JSWeakCollection*>(weak_collection_obj); 2686ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); 268728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Object** anchor = reinterpret_cast<Object**>(table->address()); 26887c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org for (int i = 0; i < table->Capacity(); i++) { 2689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { 269028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Object** key_slot = 269128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org HeapObject::RawField(table, FixedArray::OffsetOfElementAt( 269228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org ObjectHashTable::EntryToIndex(i))); 269328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org RecordSlot(anchor, key_slot, *key_slot); 269428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org Object** value_slot = 269528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org HeapObject::RawField(table, FixedArray::OffsetOfElementAt( 269628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org ObjectHashTable::EntryToValueIndex(i))); 2697b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkCompactMarkingVisitor::MarkObjectByPointer( 2698b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org this, anchor, value_slot); 26997c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org } 27007c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org } 2701ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org weak_collection_obj = weak_collection->next(); 27027c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org } 27037c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org} 27047c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 27057c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 2706ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MarkCompactCollector::ClearWeakCollections() { 2707ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKCOLLECTION_CLEAR); 2708ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Object* weak_collection_obj = encountered_weak_collections(); 2709ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org while (weak_collection_obj != Smi::FromInt(0)) { 2710ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ASSERT(MarkCompactCollector::IsMarked( 2711ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HeapObject::cast(weak_collection_obj))); 2712ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSWeakCollection* weak_collection = 2713ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org reinterpret_cast<JSWeakCollection*>(weak_collection_obj); 2714ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); 27157c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org for (int i = 0; i < table->Capacity(); i++) { 2716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { 2717c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org table->RemoveEntry(i); 27187c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org } 27197c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org } 2720ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org weak_collection_obj = weak_collection->next(); 2721ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org weak_collection->set_next(Smi::FromInt(0)); 27227c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org } 2723ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org set_encountered_weak_collections(Smi::FromInt(0)); 27247c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org} 27257c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 2726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2727c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// We scavange new space simultaneously with sweeping. This is done in two 2728c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// passes. 272943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2730c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// The first pass migrates all alive objects from one semispace to another or 2731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// promotes them to old space. Forwarding address is written directly into 2732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// first word of object without any encoding. If object is dead we write 2733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// NULL as a forwarding address. 273443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2735c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// The second pass updates pointers to new space in all spaces. It is possible 2736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// to encounter pointers to dead new space objects during traversal of pointers 2737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// to new space. We should clear them to avoid encountering them during next 2738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// pointer iteration. This is an issue if the store buffer overflows and we 2739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// have to scan the entire old space, including dead objects, looking for 2740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// pointers to new space. 2741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::MigrateObject(Address dst, 2742c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address src, 2743c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int size, 2744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AllocationSpace dest) { 2745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HEAP_PROFILE(heap(), ObjectMoveEvent(src, dst)); 2746db6d1aeaeb171233a6b1b34243387148e0068194mstarzinger@chromium.org // TODO(hpayer): Replace these checks with asserts. 2747db6d1aeaeb171233a6b1b34243387148e0068194mstarzinger@chromium.org CHECK(heap()->AllowedToBeMigrated(HeapObject::FromAddress(src), dest)); 274883fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org CHECK(dest != LO_SPACE && size <= Page::kMaxNonCodeHeapObjectSize); 274983fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org if (dest == OLD_POINTER_SPACE) { 2750c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address src_slot = src; 2751c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address dst_slot = dst; 2752c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsAligned(size, kPointerSize)); 2753c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2754c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int remaining = size / kPointerSize; remaining > 0; remaining--) { 2755c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object* value = Memory::Object_at(src_slot); 2756c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2757c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Memory::Object_at(dst_slot) = value; 2758c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2759c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (heap_->InNewSpace(value)) { 2760c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->store_buffer()->Mark(dst_slot); 2761c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { 2762c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::AddTo(&slots_buffer_allocator_, 2763c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &migration_slots_buffer_, 2764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com reinterpret_cast<Object**>(dst_slot), 2765c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::IGNORE_OVERFLOW); 2766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 276743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2768c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com src_slot += kPointerSize; 2769c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com dst_slot += kPointerSize; 277043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 277143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2772c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (compacting_ && HeapObject::FromAddress(dst)->IsJSFunction()) { 2773c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address code_entry_slot = dst + JSFunction::kCodeEntryOffset; 2774c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address code_entry = Memory::Address_at(code_entry_slot); 277543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2776c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { 2777c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::AddTo(&slots_buffer_allocator_, 2778c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &migration_slots_buffer_, 2779c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::CODE_ENTRY_SLOT, 2780c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com code_entry_slot, 2781c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::IGNORE_OVERFLOW); 278243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 278343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2784c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (dest == CODE_SPACE) { 2785876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org PROFILE(isolate(), CodeMoveEvent(src, dst)); 2786c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->MoveBlock(dst, src, size); 2787c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::AddTo(&slots_buffer_allocator_, 2788c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &migration_slots_buffer_, 2789c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::RELOCATED_CODE_OBJECT, 2790c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com dst, 2791c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::IGNORE_OVERFLOW); 2792c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Code::cast(HeapObject::FromAddress(dst))->Relocate(dst - src); 279330ce411529579186181838984710b0b0980857aaricow@chromium.org } else { 2794c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(dest == OLD_DATA_SPACE || dest == NEW_SPACE); 2795c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->MoveBlock(dst, src, size); 279630ce411529579186181838984710b0b0980857aaricow@chromium.org } 2797b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org Memory::Address_at(src) = dst; 2798b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org} 2799b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2800b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2801b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org// Visitor for updating pointers from live objects in old spaces to new space. 2802b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org// It does not expect to encounter pointers to dead objects. 2803c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass PointersUpdatingVisitor: public ObjectVisitor { 2804b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org public: 2805c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) { } 2806ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2807b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org void VisitPointer(Object** p) { 2808c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UpdatePointer(p); 2809b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org } 2810b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 28112ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org void VisitPointers(Object** start, Object** end) { 28122ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org for (Object** p = start; p < end; p++) UpdatePointer(p); 2813c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2814c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2815b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org void VisitEmbeddedPointer(RelocInfo* rinfo) { 2816b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); 2817b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org Object* target = rinfo->target_object(); 281889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Object* old_target = target; 2819b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org VisitPointer(&target); 282089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org // Avoid unnecessary changes that might unnecessary flush the instruction 282189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org // cache. 282289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (target != old_target) { 282389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org rinfo->set_target_object(target); 282489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org } 2825b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org } 2826b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2827b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org void VisitCodeTarget(RelocInfo* rinfo) { 2828b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); 2829b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); 283089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Object* old_target = target; 2831b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org VisitPointer(&target); 283289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (target != old_target) { 283389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org rinfo->set_target_address(Code::cast(target)->instruction_start()); 283489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org } 2835b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org } 2836b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2837e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org void VisitCodeAgeSequence(RelocInfo* rinfo) { 2838e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ASSERT(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); 2839e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Object* stub = rinfo->code_age_stub(); 2840e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ASSERT(stub != NULL); 2841e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org VisitPointer(&stub); 2842e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (stub != rinfo->code_age_stub()) { 2843e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org rinfo->set_code_age_stub(Code::cast(stub)); 2844e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 2845e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 2846e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 2847b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org void VisitDebugTarget(RelocInfo* rinfo) { 28482356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && 28492356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org rinfo->IsPatchedReturnSequence()) || 28502356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 28512356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org rinfo->IsPatchedDebugBreakSlotSequence())); 2852b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); 2853b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org VisitPointer(&target); 2854b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org rinfo->set_call_address(Code::cast(target)->instruction_start()); 2855b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org } 2856e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 2857c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static inline void UpdateSlot(Heap* heap, Object** slot) { 2858c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object* obj = *slot; 2859c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2860c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!obj->IsHeapObject()) return; 2861c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2862c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* heap_obj = HeapObject::cast(obj); 2863c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2864c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MapWord map_word = heap_obj->map_word(); 2865c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (map_word.IsForwardingAddress()) { 2866c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(heap->InFromSpace(heap_obj) || 2867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkCompactCollector::IsOnEvacuationCandidate(heap_obj)); 2868c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* target = map_word.ToForwardingAddress(); 2869c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *slot = target; 2870c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!heap->InFromSpace(target) && 2871c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !MarkCompactCollector::IsOnEvacuationCandidate(target)); 2872c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2873c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2874c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2875ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org private: 2876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void UpdatePointer(Object** p) { 2877c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UpdateSlot(heap_, p); 2878c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2879c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2880ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap_; 2881b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}; 2882b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 288330ce411529579186181838984710b0b0980857aaricow@chromium.org 2884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void UpdatePointer(HeapObject** p, HeapObject* object) { 2885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(*p == object); 2886b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2887c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address old_addr = object->address(); 2888b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2889b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org Address new_addr = Memory::Address_at(old_addr); 2890b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The new space sweep will overwrite the map word of dead objects 2892c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // with NULL. In this case we do not need to transfer this entry to 2893c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the store buffer which we are rebuilding. 2894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (new_addr != NULL) { 289530ce411529579186181838984710b0b0980857aaricow@chromium.org *p = HeapObject::FromAddress(new_addr); 2896c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We have to zap this pointer, because the store buffer may overflow later, 2898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and then we have to scan the entire heap and we don't want to find 2899c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // spurious newspace pointers in the old space. 290015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // TODO(mstarzinger): This was changed to a sentinel value to track down 290115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // rare crashes, change it back to Smi::FromInt(0) later. 290215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org *p = reinterpret_cast<HeapObject*>(Smi::FromInt(0x0f100d00 >> 1)); // flood 290330ce411529579186181838984710b0b0980857aaricow@chromium.org } 2904b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org} 2905b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2906b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2907c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic String* UpdateReferenceInExternalStringTableEntry(Heap* heap, 2908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object** p) { 2909c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MapWord map_word = HeapObject::cast(*p)->map_word(); 2910c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (map_word.IsForwardingAddress()) { 2912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return String::cast(map_word.ToForwardingAddress()); 2913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2914c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return String::cast(*p); 2916b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org} 2917b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2918b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MarkCompactCollector::TryPromoteObject(HeapObject* object, 2920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int object_size) { 292183fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org // TODO(hpayer): Replace that check with an assert. 292283fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org CHECK(object_size <= Page::kMaxNonCodeHeapObjectSize); 2923b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 292483fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org OldSpace* target_space = heap()->TargetSpace(object); 292583fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org 292683fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org ASSERT(target_space == heap()->old_pointer_space() || 292783fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org target_space == heap()->old_data_space()); 292883fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org Object* result; 292983fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org MaybeObject* maybe_result = target_space->AllocateRaw(object_size); 293083fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org if (maybe_result->ToObject(&result)) { 293183fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org HeapObject* target = HeapObject::cast(result); 293283fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org MigrateObject(target->address(), 293383fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org object->address(), 293483fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org object_size, 293583fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org target_space->identity()); 293683fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org heap()->mark_compact_collector()->tracer()-> 293783fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org increment_promoted_objects_size(object_size); 293883fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org return true; 2939b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org } 2940b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2941b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org return false; 2942b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org} 2943b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2944b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EvacuateNewSpace() { 2946ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // There are soft limits in the allocation code, designed trigger a mark 2947ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // sweep collection by failing allocations. But since we are already in 2948ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // a mark-sweep allocation, there is no sense in trying to trigger one. 2949ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org AlwaysAllocateScope scope; 2950c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->CheckNewSpaceExpansionCriteria(); 2951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2952c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpace* new_space = heap()->new_space(); 2953b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2954c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store allocation range before flipping semispaces. 2955c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address from_bottom = new_space->bottom(); 2956c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address from_top = new_space->top(); 2957b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2958b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org // Flip the semispaces. After flipping, to space is empty, from space has 2959b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org // live objects. 2960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com new_space->Flip(); 2961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com new_space->ResetAllocationInfo(); 2962b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2963b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org int survivors_size = 0; 2964b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2965b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org // First pass: traverse all objects in inactive semispace, remove marks, 2966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // migrate live objects and write forwarding addresses. This stage puts 2967c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // new entries in the store buffer and may cause some pages to be marked 2968c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // scan-on-scavenge. 2969169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org NewSpacePageIterator it(from_bottom, from_top); 2970169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org while (it.has_next()) { 2971169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org NewSpacePage* p = it.next(); 2972169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org survivors_size += DiscoverAndPromoteBlackObjectsOnPage(new_space, p); 2973b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org } 2974b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2975c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->IncrementYoungSurvivorsCounter(survivors_size); 2976c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com new_space->set_age_mark(new_space->top()); 2977c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2978b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 29794a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 2980c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) { 2981c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AlwaysAllocateScope always_allocate; 2982c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 2983c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(p->IsEvacuationCandidate() && !p->WasSwept()); 2984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->MarkSweptPrecisely(); 2985b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 2986c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offsets[16]; 298743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 298810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { 298910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Address cell_base = it.CurrentCellBase(); 299010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBit::CellType* cell = it.CurrentCell(); 299110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 299210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (*cell == 0) continue; 299343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 299410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org int live_objects = MarkWordToObjectStarts(*cell, offsets); 2995c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < live_objects; i++) { 2996c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address object_addr = cell_base + offsets[i] * kPointerSize; 2997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* object = HeapObject::FromAddress(object_addr); 2998c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); 2999013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3000c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int size = object->Size(); 3001013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3002c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MaybeObject* target = space->AllocateRaw(size); 3003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (target->IsFailure()) { 3004c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // OS refused to give us memory. 3005c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com V8::FatalProcessOutOfMemory("Evacuation"); 3006c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return; 3007c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3008013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3009c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object* target_object = target->ToObjectUnchecked(); 3010013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3011c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MigrateObject(HeapObject::cast(target_object)->address(), 3012c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object_addr, 3013c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size, 3014c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space->identity()); 3015c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(object->map_word().IsForwardingAddress()); 3016c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3017013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3018c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clear marking bits for current cell. 301910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org *cell = 0; 3020c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3021c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->ResetLiveBytes(); 3022c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3023013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 302443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EvacuatePages() { 3026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int npages = evacuation_candidates_.length(); 3027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < npages; i++) { 3028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = evacuation_candidates_[i]; 3029c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(p->IsEvacuationCandidate() || 3030c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 3031c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (p->IsEvacuationCandidate()) { 3032c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // During compaction we might have to request a new page. 3033c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that space still have room for that. 3034c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (static_cast<PagedSpace*>(p->owner())->CanExpand()) { 3035c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EvacuateLiveObjectsFromPage(p); 303643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 3037c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Without room for expansion evacuation is not guaranteed to succeed. 3038c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Pessimistically abandon unevacuated pages. 3039c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int j = i; j < npages; j++) { 3040c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* page = evacuation_candidates_[j]; 3041c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address()); 3042c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com page->ClearEvacuationCandidate(); 3043c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com page->SetFlag(Page::RESCAN_ON_EVACUATION); 30446e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org page->InsertAfter(static_cast<PagedSpace*>(page->owner())->anchor()); 304543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3046c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return; 304743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 304843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3049c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3050c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 305143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3052013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3053c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass EvacuationWeakObjectRetainer : public WeakObjectRetainer { 3054c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 3055c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual Object* RetainAs(Object* object) { 3056c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (object->IsHeapObject()) { 3057c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* heap_object = HeapObject::cast(object); 3058c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MapWord map_word = heap_object->map_word(); 3059c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (map_word.IsForwardingAddress()) { 3060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return map_word.ToForwardingAddress(); 3061013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org } 3062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return object; 3064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 3066013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3067013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline void UpdateSlot(ObjectVisitor* v, 3069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::SlotType slot_type, 3070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address addr) { 3071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com switch (slot_type) { 3072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case SlotsBuffer::CODE_TARGET_SLOT: { 3073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RelocInfo rinfo(addr, RelocInfo::CODE_TARGET, 0, NULL); 3074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com rinfo.Visit(v); 3075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 3076013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org } 3077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case SlotsBuffer::CODE_ENTRY_SLOT: { 3078c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com v->VisitCodeEntry(addr); 3079c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 3080c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case SlotsBuffer::RELOCATED_CODE_OBJECT: { 3082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* obj = HeapObject::FromAddress(addr); 3083c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Code::cast(obj)->CodeIterateBody(v); 3084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 3085c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case SlotsBuffer::DEBUG_TARGET_SLOT: { 3087c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RelocInfo rinfo(addr, RelocInfo::DEBUG_BREAK_SLOT, 0, NULL); 3088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (rinfo.IsPatchedDebugBreakSlotSequence()) rinfo.Visit(v); 3089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 3090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case SlotsBuffer::JS_RETURN_SLOT: { 3092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RelocInfo rinfo(addr, RelocInfo::JS_RETURN, 0, NULL); 3093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(v); 3094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 3095c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3096b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org case SlotsBuffer::EMBEDDED_OBJECT_SLOT: { 3097b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org RelocInfo rinfo(addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL); 3098b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org rinfo.Visit(v); 3099b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org break; 3100b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } 3101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com default: 3102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UNREACHABLE(); 3103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 3104013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org } 3105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3107013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum SweepingMode { 3109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SWEEP_ONLY, 3110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SWEEP_AND_VISIT_LIVE_OBJECTS 3111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 3112013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3113013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum SkipListRebuildingMode { 3115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com REBUILD_SKIP_LIST, 3116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com IGNORE_SKIP_LIST 3117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 3118013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3119013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 3120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Sweep a space precisely. After this has been done the space can 3121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// be iterated precisely, hitting only the live objects. Code space 3122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// is always swept precisely because we want to be able to iterate 3123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// over it. Map space is swept precisely, because it is not compacted. 3124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Slots in live objects pointing into evacuation candidates are updated 3125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// if requested. 3126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comtemplate<SweepingMode sweeping_mode, SkipListRebuildingMode skip_list_mode> 3127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void SweepPrecisely(PagedSpace* space, 3128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p, 3129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ObjectVisitor* v) { 3130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(skip_list_mode == REBUILD_SKIP_LIST, 3132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space->identity() == CODE_SPACE); 3133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); 3134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3135e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org double start_time = 0.0; 3136e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org if (FLAG_print_cumulative_gc_stat) { 3137e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org start_time = OS::TimeCurrentMillis(); 3138e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 3139e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->MarkSweptPrecisely(); 3141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3142ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address free_start = p->area_start(); 3143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 3144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offsets[16]; 3145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SkipList* skip_list = p->skip_list(); 3147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int curr_region = -1; 3148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { 3149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com skip_list->Clear(); 3150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 315210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { 315310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Address cell_base = it.CurrentCellBase(); 315410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBit::CellType* cell = it.CurrentCell(); 315510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org int live_objects = MarkWordToObjectStarts(*cell, offsets); 3156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int live_index = 0; 3157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for ( ; live_objects != 0; live_objects--) { 315810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Address free_end = cell_base + offsets[live_index++] * kPointerSize; 3159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (free_end != free_start) { 3160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space->Free(free_start, static_cast<int>(free_end - free_start)); 3161c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#ifdef ENABLE_GDB_JIT_INTERFACE 3162c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (FLAG_gdbjit && space->identity() == CODE_SPACE) { 3163c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org GDBJITInterface::RemoveCodeRange(free_start, free_end); 3164c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 3165c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#endif 3166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* live_object = HeapObject::FromAddress(free_end); 3168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); 3169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Map* map = live_object->map(); 3170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int size = live_object->SizeFromMap(map); 3171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { 3172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com live_object->IterateBody(map->instance_type(), size, v); 3173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { 3175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int new_region_start = 3176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SkipList::RegionNumber(free_end); 3177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int new_region_end = 3178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SkipList::RegionNumber(free_end + size - kPointerSize); 3179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (new_region_start != curr_region || 3180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com new_region_end != curr_region) { 3181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com skip_list->AddObject(free_end, size); 3182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com curr_region = new_region_end; 3183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com free_start = free_end + size; 318643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clear marking bits for current cell. 318810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org *cell = 0; 318943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3190ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org if (free_start != p->area_end()) { 3191ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org space->Free(free_start, static_cast<int>(p->area_end() - free_start)); 3192c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#ifdef ENABLE_GDB_JIT_INTERFACE 3193c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (FLAG_gdbjit && space->identity() == CODE_SPACE) { 3194c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org GDBJITInterface::RemoveCodeRange(free_start, p->area_end()); 3195c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 3196c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#endif 3197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->ResetLiveBytes(); 3199e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org if (FLAG_print_cumulative_gc_stat) { 3200e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org space->heap()->AddSweepingTime(OS::TimeCurrentMillis() - start_time); 3201e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 320243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 320343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 320443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) { 3206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = Page::FromAddress(code->address()); 32079258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 3208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (p->IsEvacuationCandidate() || 3209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 3210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return false; 3211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 321243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address code_start = code->address(); 3214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address code_end = code_start + code->Size(); 321543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t start_index = MemoryChunk::FastAddressToMarkbitIndex(code_start); 3217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t end_index = 3218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::FastAddressToMarkbitIndex(code_end - kPointerSize); 3219defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 3220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Bitmap* b = p->markbits(); 3221defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 3222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit start_mark_bit = b->MarkBitFromIndex(start_index); 3223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit end_mark_bit = b->MarkBitFromIndex(end_index); 322443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit::CellType* start_cell = start_mark_bit.cell(); 3226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit::CellType* end_cell = end_mark_bit.cell(); 322743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (value) { 3229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit::CellType start_mask = ~(start_mark_bit.mask() - 1); 3230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit::CellType end_mask = (end_mark_bit.mask() << 1) - 1; 323143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (start_cell == end_cell) { 3233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *start_cell |= start_mask & end_mask; 3234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 3235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *start_cell |= start_mask; 3236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (MarkBit::CellType* cell = start_cell + 1; cell < end_cell; cell++) { 3237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *cell = ~0; 3238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *end_cell |= end_mask; 3240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 3242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (MarkBit::CellType* cell = start_cell ; cell <= end_cell; cell++) { 3243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *cell = 0; 3244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 32450c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 32460c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return true; 3248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 32490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 32500c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic bool IsOnInvalidatedCodeObject(Address addr) { 3252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We did not record any slots in large objects thus 3253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // we can safely go to the page from the slot address. 3254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = Page::FromAddress(addr); 32550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // First check owner's identity because old pointer and old data spaces 3257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // are swept lazily and might still have non-zero mark-bits on some 3258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // pages. 3259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (p->owner()->identity() != CODE_SPACE) return false; 32600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // In code space only bits on evacuation candidates (but we don't record 3262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // any slots on them) and under invalidated code objects are non-zero. 3263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark_bit = 3264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); 32650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return mark_bit.Get(); 3267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 32680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 32690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::InvalidateCode(Code* code) { 3271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (heap_->incremental_marking()->IsCompacting() && 3272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !ShouldSkipEvacuationSlotRecording(code)) { 3273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(compacting_); 32740c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the object is white than no slots were recorded on it yet. 3276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit mark_bit = Marking::MarkBitFrom(code); 3277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (Marking::IsWhite(mark_bit)) return; 32780c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com invalidated_code_.Add(code); 32800c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 3281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 32820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3283c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 3284fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// Return true if the given code is deoptimized or will be deoptimized. 3285fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgbool MarkCompactCollector::WillBeDeoptimized(Code* code) { 3286fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // We assume the code_to_deoptimize_link is initialized to undefined. 3287fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // If it is 0, or refers to another Code object, then this code 3288fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // is already linked, or was already linked into the list. 3289fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org return code->code_to_deoptimize_link() != heap()->undefined_value() 3290fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org || code->marked_for_deoptimization(); 3291fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org} 3292fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 3293fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 3294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MarkCompactCollector::MarkInvalidatedCode() { 3295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool code_marked = false; 32960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int length = invalidated_code_.length(); 3298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < length; i++) { 3299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Code* code = invalidated_code_[i]; 3300ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 3301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (SetMarkBitsUnderInvalidatedCode(code, true)) { 3302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com code_marked = true; 33030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 3304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 33050c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return code_marked; 3307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 33080c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 33090c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::RemoveDeadInvalidatedCode() { 3311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int length = invalidated_code_.length(); 3312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < length; i++) { 3313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!IsMarked(invalidated_code_[i])) invalidated_code_[i] = NULL; 3314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 33160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 33170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::ProcessInvalidatedCode(ObjectVisitor* visitor) { 3319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int length = invalidated_code_.length(); 3320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < length; i++) { 3321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Code* code = invalidated_code_[i]; 3322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (code != NULL) { 3323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com code->Iterate(visitor); 3324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SetMarkBitsUnderInvalidatedCode(code, false); 33250c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 33260c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 3327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com invalidated_code_.Rewind(0); 3328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 33290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 33300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EvacuateNewSpaceAndCandidates() { 3332ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Heap::RelocationLock relocation_lock(heap()); 3333ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 33341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org bool code_slots_filtering_required; 33351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); 33361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org code_slots_filtering_required = MarkInvalidatedCode(); 33371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org EvacuateNewSpace(); 33381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 33390c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 33401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_EVACUATE_PAGES); 33411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org EvacuatePages(); 33421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 3343b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 3344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Second pass: find pointers to new space and update them. 3345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PointersUpdatingVisitor updating_visitor(heap()); 3346b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org 33471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org { GCTracer::Scope gc_scope(tracer_, 33481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org GCTracer::Scope::MC_UPDATE_NEW_TO_NEW_POINTERS); 33491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Update pointers in to space. 33501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SemiSpaceIterator to_it(heap()->new_space()->bottom(), 33511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org heap()->new_space()->top()); 33521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org for (HeapObject* object = to_it.Next(); 33531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org object != NULL; 33541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org object = to_it.Next()) { 33551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Map* map = object->map(); 33561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org object->IterateBody(map->instance_type(), 33571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org object->SizeFromMap(map), 33581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org &updating_visitor); 33591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 3360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 33610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 33621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org { GCTracer::Scope gc_scope(tracer_, 33631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org GCTracer::Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS); 33641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Update roots. 33651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); 33661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 33670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 33681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org { GCTracer::Scope gc_scope(tracer_, 33691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org GCTracer::Scope::MC_UPDATE_OLD_TO_NEW_POINTERS); 3370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com StoreBufferRebuildScope scope(heap_, 3371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->store_buffer(), 3372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &Heap::ScavengeStoreBufferCallback); 3373169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org heap_->store_buffer()->IteratePointersToNewSpaceAndClearMaps( 3374169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org &UpdatePointer); 3375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 33771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org { GCTracer::Scope gc_scope(tracer_, 33781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org GCTracer::Scope::MC_UPDATE_POINTERS_TO_EVACUATED); 33791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SlotsBuffer::UpdateSlotsRecordedIn(heap_, 33801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org migration_slots_buffer_, 33811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org code_slots_filtering_required); 33821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (FLAG_trace_fragmentation) { 33831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org PrintF(" migration slots buffer: %d\n", 33841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SlotsBuffer::SizeOfChain(migration_slots_buffer_)); 33851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 33861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 33871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (compacting_ && was_marked_incrementally_) { 33881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // It's difficult to filter out slots recorded for large objects. 33891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org LargeObjectIterator it(heap_->lo_space()); 33901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 33911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // LargeObjectSpace is not swept yet thus we have to skip 33921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // dead objects explicitly. 33931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!IsMarked(obj)) continue; 33941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 33951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Page* p = Page::FromAddress(obj->address()); 33961b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 33971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org obj->Iterate(&updating_visitor); 33981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org p->ClearFlag(Page::RESCAN_ON_EVACUATION); 33991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 3400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 34020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 34030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int npages = evacuation_candidates_.length(); 34051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org { GCTracer::Scope gc_scope( 34061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org tracer_, GCTracer::Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED); 34071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org for (int i = 0; i < npages; i++) { 34081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Page* p = evacuation_candidates_[i]; 34091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ASSERT(p->IsEvacuationCandidate() || 34101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 34111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 34121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (p->IsEvacuationCandidate()) { 34131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SlotsBuffer::UpdateSlotsRecordedIn(heap_, 34141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org p->slots_buffer(), 34151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org code_slots_filtering_required); 34161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (FLAG_trace_fragmentation) { 34171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org PrintF(" page %p slots buffer: %d\n", 34181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reinterpret_cast<void*>(p), 34191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SlotsBuffer::SizeOfChain(p->slots_buffer())); 34201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 3421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 34221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Important: skip list should be cleared only after roots were updated 34231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // because root iteration traverses the stack and might have to find 34241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // code objects from non-updated pc pointing into evacuation candidate. 34251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SkipList* list = p->skip_list(); 34261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (list != NULL) list->Clear(); 34271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } else { 34281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (FLAG_gc_verbose) { 34291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 34301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reinterpret_cast<intptr_t>(p)); 34311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 34321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 34331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 34341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 34351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org switch (space->identity()) { 34361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case OLD_DATA_SPACE: 3437e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 34381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org break; 34391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case OLD_POINTER_SPACE: 34401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, IGNORE_SKIP_LIST>( 34411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org space, p, &updating_visitor); 34421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org break; 34431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org case CODE_SPACE: 34441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, REBUILD_SKIP_LIST>( 34451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org space, p, &updating_visitor); 34461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org break; 34471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org default: 34481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org UNREACHABLE(); 34491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org break; 34501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 34510c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 34520c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 34530c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 34540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 34551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_UPDATE_MISC_POINTERS); 34561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 3457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Update pointers from cells. 3458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObjectIterator cell_iterator(heap_->cell_space()); 3459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (HeapObject* cell = cell_iterator.Next(); 3460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cell != NULL; 3461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cell = cell_iterator.Next()) { 346241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org if (cell->IsCell()) { 34631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Cell::BodyDescriptor::IterateBody(cell, &updating_visitor); 346441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 346541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 346641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 346741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org HeapObjectIterator js_global_property_cell_iterator( 346841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org heap_->property_cell_space()); 346941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org for (HeapObject* cell = js_global_property_cell_iterator.Next(); 347041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org cell != NULL; 347141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org cell = js_global_property_cell_iterator.Next()) { 3472b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (cell->IsPropertyCell()) { 34731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor); 34740c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 34750c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 34760c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3477fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // Update the heads of the native contexts list the code to deoptimize list. 347846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org updating_visitor.VisitPointer(heap_->native_contexts_list_address()); 3479fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org updating_visitor.VisitPointer(&code_to_deoptimize_); 34800c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 34814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org heap_->string_table()->Iterate(&updating_visitor); 34820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Update pointers from external string table. 3484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->UpdateReferencesInExternalStringTable( 3485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &UpdateReferenceInExternalStringTableEntry); 348630ce411529579186181838984710b0b0980857aaricow@chromium.org 348778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (!FLAG_watch_ic_patching) { 348878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Update JSFunction pointers from the runtime profiler. 348978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org heap()->isolate()->runtime_profiler()->UpdateSamplesAfterCompact( 349078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org &updating_visitor); 349178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 34920c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EvacuationWeakObjectRetainer evacuation_object_retainer; 3494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->ProcessWeakReferences(&evacuation_object_retainer); 34950c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Visit invalidated code (we ignored all slots on it) and clear mark-bits 3497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // under it. 3498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ProcessInvalidatedCode(&updating_visitor); 34990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 350088d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org heap_->isolate()->inner_pointer_to_code_cache()->Flush(); 350188d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org 3502c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 3503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_verify_heap) { 3504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VerifyEvacuation(heap_); 3505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 35070c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 3508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); 3509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(migration_slots_buffer_ == NULL); 35102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org} 35112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org 35122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org 35136e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid MarkCompactCollector::UnlinkEvacuationCandidates() { 35146e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org int npages = evacuation_candidates_.length(); 35156e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org for (int i = 0; i < npages; i++) { 35166e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Page* p = evacuation_candidates_[i]; 35176e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org if (!p->IsEvacuationCandidate()) continue; 35186e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org p->Unlink(); 35196e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org p->ClearSweptPrecisely(); 35206e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org p->ClearSweptConservatively(); 35216e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 35226e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 35236e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 35246e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 35252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgvoid MarkCompactCollector::ReleaseEvacuationCandidates() { 35262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org int npages = evacuation_candidates_.length(); 3527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < npages; i++) { 3528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = evacuation_candidates_[i]; 3529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!p->IsEvacuationCandidate()) continue; 3530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3531ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org space->Free(p->area_start(), p->area_size()); 3532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->set_scan_on_scavenge(false); 3533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); 3534994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org p->ResetLiveBytes(); 35356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org space->ReleasePage(p, false); 35360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 3537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com evacuation_candidates_.Rewind(0); 3538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com compacting_ = false; 35396e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org heap()->FreeQueuedChunks(); 354043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 354143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 354243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kStartTableEntriesPerLine = 5; 3544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kStartTableLines = 171; 3545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kStartTableInvalidLine = 127; 3546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kStartTableUnusedEntry = 126; 3547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#define _ kStartTableUnusedEntry 3549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#define X kStartTableInvalidLine 3550c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Mark-bit to object start offset table. 3551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 3552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// The line is indexed by the mark bits in a byte. The first number on 3553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// the line describes the number of live object starts for the line and the 3554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// other numbers on the line describe the offsets (in words) of the object 3555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// starts. 3556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 3557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Since objects are at least 2 words large we don't have entries for two 3558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// consecutive 1 bits. All entries after 170 have at least 2 consecutive bits. 3559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comchar kStartTable[kStartTableLines * kStartTableEntriesPerLine] = { 3560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 0, _, _, _, _, // 0 3561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 0, _, _, _, // 1 3562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 1, _, _, _, // 2 3563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 3 3564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 2, _, _, _, // 4 3565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 0, 2, _, _, // 5 3566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 6 3567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 7 3568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 3, _, _, _, // 8 3569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 0, 3, _, _, // 9 3570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 1, 3, _, _, // 10 3571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 11 3572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 12 3573c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 13 3574c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 14 3575c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 15 3576c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 4, _, _, _, // 16 3577c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 0, 4, _, _, // 17 3578c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 1, 4, _, _, // 18 3579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 19 3580c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 2, 4, _, _, // 20 3581c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 2, 4, _, // 21 3582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 22 3583c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 23 3584c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 24 3585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 25 3586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 26 3587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 27 3588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 28 3589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 29 3590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 30 3591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 31 3592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 5, _, _, _, // 32 3593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 0, 5, _, _, // 33 3594c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 1, 5, _, _, // 34 3595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 35 3596c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 2, 5, _, _, // 36 3597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 2, 5, _, // 37 3598c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 38 3599c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 39 3600c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 3, 5, _, _, // 40 3601c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 3, 5, _, // 41 3602c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 1, 3, 5, _, // 42 3603c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 43 3604c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 44 3605c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 45 3606c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 46 3607c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 47 3608c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 48 3609c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 49 3610c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 50 3611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 51 3612c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 52 3613c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 53 3614c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 54 3615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 55 3616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 56 3617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 57 3618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 58 3619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 59 3620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 60 3621c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 61 3622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 62 3623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 63 3624c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 6, _, _, _, // 64 3625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 0, 6, _, _, // 65 3626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 1, 6, _, _, // 66 3627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 67 3628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 2, 6, _, _, // 68 3629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 2, 6, _, // 69 3630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 70 3631c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 71 3632c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 3, 6, _, _, // 72 3633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 3, 6, _, // 73 3634c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 1, 3, 6, _, // 74 3635c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 75 3636c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 76 3637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 77 3638c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 78 3639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 79 3640c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 4, 6, _, _, // 80 3641c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 4, 6, _, // 81 3642c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 1, 4, 6, _, // 82 3643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 83 3644c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 2, 4, 6, _, // 84 3645c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4, 0, 2, 4, 6, // 85 3646c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 86 3647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 87 3648c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 88 3649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 89 3650c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 90 3651c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 91 3652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 92 3653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 93 3654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 94 3655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 95 3656c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 96 3657c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 97 3658c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 98 3659c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 99 3660c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 100 3661c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 101 3662c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 102 3663c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 103 3664c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 104 3665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 105 3666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 106 3667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 107 3668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 108 3669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 109 3670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 110 3671c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 111 3672c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 112 3673c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 113 3674c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 114 3675c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 115 3676c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 116 3677c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 117 3678c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 118 3679c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 119 3680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 120 3681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 121 3682c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 122 3683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 123 3684c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 124 3685c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 125 3686c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 126 3687c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 127 3688c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1, 7, _, _, _, // 128 3689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 0, 7, _, _, // 129 3690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 1, 7, _, _, // 130 3691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 131 3692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 2, 7, _, _, // 132 3693c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 2, 7, _, // 133 3694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 134 3695c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 135 3696c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 3, 7, _, _, // 136 3697c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 3, 7, _, // 137 3698c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 1, 3, 7, _, // 138 3699c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 139 3700c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 140 3701c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 141 3702c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 142 3703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 143 3704c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 4, 7, _, _, // 144 3705c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 4, 7, _, // 145 3706c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 1, 4, 7, _, // 146 3707c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 147 3708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 2, 4, 7, _, // 148 3709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4, 0, 2, 4, 7, // 149 3710c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 150 3711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 151 3712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 152 3713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 153 3714c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 154 3715c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 155 3716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 156 3717c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 157 3718c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 158 3719c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 159 3720c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2, 5, 7, _, _, // 160 3721c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 0, 5, 7, _, // 161 3722c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 1, 5, 7, _, // 162 3723c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 163 3724c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 2, 5, 7, _, // 164 3725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4, 0, 2, 5, 7, // 165 3726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 166 3727c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com X, _, _, _, _, // 167 3728c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3, 3, 5, 7, _, // 168 3729c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4, 0, 3, 5, 7, // 169 3730c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4, 1, 3, 5, 7 // 170 3731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 3732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#undef _ 3733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#undef X 3734c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3735c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Takes a word of mark bits. Returns the number of objects that start in the 3737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// range. Puts the offsets of the words in the supplied array. 3738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts) { 3739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int objects = 0; 3740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset = 0; 3741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3742c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // No consecutive 1 bits. 3743c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((mark_bits & 0x180) != 0x180); 3744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((mark_bits & 0x18000) != 0x18000); 3745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((mark_bits & 0x1800000) != 0x1800000); 3746c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3747c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (mark_bits != 0) { 3748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int byte = (mark_bits & 0xff); 3749c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com mark_bits >>= 8; 3750c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (byte != 0) { 3751c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(byte < kStartTableLines); // No consecutive 1 bits. 3752c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com char* table = kStartTable + byte * kStartTableEntriesPerLine; 3753c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int objects_in_these_8_words = table[0]; 3754c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(objects_in_these_8_words != kStartTableInvalidLine); 3755c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(objects_in_these_8_words < kStartTableEntriesPerLine); 3756c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < objects_in_these_8_words; i++) { 3757c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com starts[objects++] = offset + table[1 + i]; 3758c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 375943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3760c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com offset += 8; 376143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3762c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return objects; 376343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 376443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 376543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline Address DigestFreeStart(Address approximate_free_start, 3767c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t free_start_cell) { 3768c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(free_start_cell != 0); 376943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3770c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // No consecutive 1 bits. 3771c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((free_start_cell & (free_start_cell << 1)) == 0); 377243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3773c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offsets[16]; 3774c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t cell = free_start_cell; 3775c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset_of_last_live; 3776c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((cell & 0x80000000u) != 0) { 3777c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // This case would overflow below. 3778c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com offset_of_last_live = 31; 3779c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 3780c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Remove all but one bit, the most significant. This is an optimization 3781c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // that may or may not be worthwhile. 3782c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cell |= cell >> 16; 3783c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cell |= cell >> 8; 3784c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cell |= cell >> 4; 3785c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cell |= cell >> 2; 3786c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cell |= cell >> 1; 3787c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cell = (cell + 1) >> 1; 3788c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int live_objects = MarkWordToObjectStarts(cell, offsets); 3789c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(live_objects == 1); 3790c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com offset_of_last_live = offsets[live_objects - 1]; 3791c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3792c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address last_live_start = 3793c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com approximate_free_start + offset_of_last_live * kPointerSize; 3794c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* last_live = HeapObject::FromAddress(last_live_start); 3795c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address free_start = last_live_start + last_live->Size(); 3796c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return free_start; 3797c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3798c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3799c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3800c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline Address StartOfLiveObject(Address block_address, uint32_t cell) { 3801c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(cell != 0); 3802c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3803c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // No consecutive 1 bits. 3804c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((cell & (cell << 1)) == 0); 3805c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3806c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offsets[16]; 3807c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (cell == 0x80000000u) { // Avoid overflow below. 3808c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return block_address + 31 * kPointerSize; 3809c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3810c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t first_set_bit = ((cell ^ (cell - 1)) + 1) >> 1; 3811c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((first_set_bit & cell) == first_set_bit); 3812c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int live_objects = MarkWordToObjectStarts(first_set_bit, offsets); 3813c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(live_objects == 1); 3814c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com USE(live_objects); 3815c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return block_address + offsets[0] * kPointerSize; 3816c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3817c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3818c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3819e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgtemplate<MarkCompactCollector::SweepingParallelism mode> 3820e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgstatic intptr_t Free(PagedSpace* space, 3821e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org FreeList* free_list, 3822e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org Address start, 3823e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org int size) { 3824e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org if (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY) { 3825e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org return space->Free(start, size); 3826e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } else { 3827e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org return size - free_list->Free(start, size); 3828e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 3829e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 3830e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3831e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3832e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org// Force instantiation of templatized SweepConservatively method for 3833e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org// SWEEP_SEQUENTIALLY mode. 3834e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgtemplate intptr_t MarkCompactCollector:: 3835e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org SweepConservatively<MarkCompactCollector::SWEEP_SEQUENTIALLY>( 3836e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org PagedSpace*, FreeList*, Page*); 3837e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3838e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3839e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org// Force instantiation of templatized SweepConservatively method for 3840e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org// SWEEP_IN_PARALLEL mode. 3841e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgtemplate intptr_t MarkCompactCollector:: 3842e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org SweepConservatively<MarkCompactCollector::SWEEP_IN_PARALLEL>( 3843e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org PagedSpace*, FreeList*, Page*); 3844e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3845e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3846c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Sweeps a space conservatively. After this has been done the larger free 3847c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// spaces have been put on the free list and the smaller ones have been 3848c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// ignored and left untouched. A free space is always either ignored or put 3849c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// on the free list, never split up into two parts. This is important 3850c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// because it means that any FreeSpace maps left actually describe a region of 3851c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// memory that can be ignored when scanning. Dead objects other than free 3852c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// spaces will not contain the free space map. 3853e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgtemplate<MarkCompactCollector::SweepingParallelism mode> 3854e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgintptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, 3855e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org FreeList* free_list, 3856e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org Page* p) { 3857c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3858e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && 3859e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org free_list != NULL) || 3860e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY && 3861e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org free_list == NULL)); 3862e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3863c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->MarkSweptConservatively(); 3864c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3865c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com intptr_t freed_bytes = 0; 386610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org size_t size = 0; 3867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3868c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip over all the dead objects at the start of the page and mark them free. 386910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Address cell_base = 0; 387010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBit::CellType* cell = NULL; 387110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBitCellIterator it(p); 387210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (; !it.Done(); it.Advance()) { 387310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org cell_base = it.CurrentCellBase(); 387410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org cell = it.CurrentCell(); 387510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (*cell != 0) break; 3876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 387710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 387810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (it.Done()) { 387910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org size = p->area_end() - p->area_start(); 3880e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org freed_bytes += Free<mode>(space, free_list, p->area_start(), 3881e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org static_cast<int>(size)); 3882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, p->LiveBytes()); 3883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return freed_bytes; 3884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 388510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 3886c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Grow the size of the start-of-page free space a little to get up to the 3887c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // first live object. 388810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Address free_end = StartOfLiveObject(cell_base, *cell); 3889c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Free the first free space. 3890ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org size = free_end - p->area_start(); 3891e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org freed_bytes += Free<mode>(space, free_list, p->area_start(), 3892e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org static_cast<int>(size)); 3893e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The start of the current free area is represented in undigested form by 3895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the address of the last 32-word section that contained a live object and 3896c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the marking bitmap for that cell, which describes where the live object 3897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // started. Unless we find a large free space in the bitmap we will not 3898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // digest this pair into a real address. We start the iteration here at the 3899c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // first word in the marking bit map that indicates a live object. 390010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org Address free_start = cell_base; 390110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org MarkBit::CellType free_start_cell = *cell; 390210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 390310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org for (; !it.Done(); it.Advance()) { 390410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org cell_base = it.CurrentCellBase(); 390510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org cell = it.CurrentCell(); 390610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (*cell != 0) { 3907c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We have a live object. Check approximately whether it is more than 32 3908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // words since the last live object. 390910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (cell_base - free_start > 32 * kPointerSize) { 3910c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com free_start = DigestFreeStart(free_start, free_start_cell); 391110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (cell_base - free_start > 32 * kPointerSize) { 3912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Now that we know the exact start of the free space it still looks 3913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // like we have a large enough free space to be worth bothering with. 3914c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // so now we need to find the start of the first live object at the 3915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // end of the free space. 391610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org free_end = StartOfLiveObject(cell_base, *cell); 3917e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org freed_bytes += Free<mode>(space, free_list, free_start, 3918e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org static_cast<int>(free_end - free_start)); 3919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Update our undigested record of where the current free area started. 392210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org free_start = cell_base; 392310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org free_start_cell = *cell; 3924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clear marking bits for current cell. 392510480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org *cell = 0; 3926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 392743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 392843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Handle the free space at the end of the page. 393010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (cell_base - free_start > 32 * kPointerSize) { 3931c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com free_start = DigestFreeStart(free_start, free_start_cell); 3932e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org freed_bytes += Free<mode>(space, free_list, free_start, 393310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org static_cast<int>(p->area_end() - free_start)); 3934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 393543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->ResetLiveBytes(); 3937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return freed_bytes; 3938c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 393943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3940ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 3941e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgvoid MarkCompactCollector::SweepInParallel(PagedSpace* space, 3942e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org FreeList* private_free_list, 3943e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org FreeList* free_list) { 3944e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org PageIterator it(space); 3945e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org while (it.has_next()) { 3946e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org Page* p = it.next(); 3947e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3948e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org if (p->TryParallelSweeping()) { 3949e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org SweepConservatively<SWEEP_IN_PARALLEL>(space, private_free_list, p); 3950e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org free_list->Concatenate(private_free_list); 3951e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 3952e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 3953e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 3954e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 3955e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 39561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgvoid MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 3957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 39587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org sweeper == LAZY_CONSERVATIVE || 39592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org sweeper == PARALLEL_CONSERVATIVE || 39602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org sweeper == CONCURRENT_CONSERVATIVE); 3961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com space->ClearStats(); 3962cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager 3963c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PageIterator it(space); 39642bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com 39651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int pages_swept = 0; 3966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool lazy_sweeping_active = false; 3967c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool unused_page_present = false; 3968750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org bool parallel_sweeping_active = false; 3969c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 3970c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (it.has_next()) { 3971c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* p = it.next(); 3972c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 3973e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org ASSERT(p->parallel_sweeping() == 0); 39746e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org ASSERT(!p->IsEvacuationCandidate()); 39756e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3976c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clear sweeping flags indicating that marking bits are still intact. 3977c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->ClearSweptPrecisely(); 3978c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com p->ClearSweptConservatively(); 3979cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager 3980c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 3981c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Will be processed in EvacuateNewSpaceAndCandidates. 39826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org ASSERT(evacuation_candidates_.length() > 0); 3983c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com continue; 3984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 3985cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager 3986c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // One unused page is kept, all further are released before sweeping them. 3987c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (p->LiveBytes() == 0) { 3988c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (unused_page_present) { 3989c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_gc_verbose) { 3990c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PrintF("Sweeping 0x%" V8PRIxPTR " released page.\n", 3991c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com reinterpret_cast<intptr_t>(p)); 3992c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 39932efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Adjust unswept free bytes because releasing a page expects said 39942efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // counter to be accurate for unswept pages. 39952efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org space->IncreaseUnsweptFreeBytes(p); 39966e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org space->ReleasePage(p, true); 3997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com continue; 3998cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager } 3999c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com unused_page_present = true; 400043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 4001cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager 4002c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com switch (sweeper) { 4003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case CONSERVATIVE: { 40041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (FLAG_gc_verbose) { 40051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 40061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reinterpret_cast<intptr_t>(p)); 40071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 4008e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 40091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org pages_swept++; 4010c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 4011c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4012c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case LAZY_CONSERVATIVE: { 4013750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (lazy_sweeping_active) { 4014750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (FLAG_gc_verbose) { 4015750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org PrintF("Sweeping 0x%" V8PRIxPTR " lazily postponed.\n", 4016750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org reinterpret_cast<intptr_t>(p)); 4017750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 4018750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org space->IncreaseUnsweptFreeBytes(p); 4019750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else { 4020750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (FLAG_gc_verbose) { 4021750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 4022750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org reinterpret_cast<intptr_t>(p)); 4023750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 4024750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 4025750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org pages_swept++; 4026750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org space->SetPagesToSweep(p->next_page()); 4027750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org lazy_sweeping_active = true; 40281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 4029c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 4030c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 40312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org case CONCURRENT_CONSERVATIVE: 4032e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org case PARALLEL_CONSERVATIVE: { 4033750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (!parallel_sweeping_active) { 4034750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (FLAG_gc_verbose) { 4035750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 4036750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org reinterpret_cast<intptr_t>(p)); 4037750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 4038750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p); 4039750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org pages_swept++; 4040750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org parallel_sweeping_active = true; 4041750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else { 4042750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (FLAG_gc_verbose) { 4043750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org PrintF("Sweeping 0x%" V8PRIxPTR " conservatively in parallel.\n", 4044750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org reinterpret_cast<intptr_t>(p)); 4045750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 4046750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org p->set_parallel_sweeping(1); 4047750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org space->IncreaseUnsweptFreeBytes(p); 4048e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 4049e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org break; 4050e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 4051c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case PRECISE: { 40521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (FLAG_gc_verbose) { 40531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n", 40541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org reinterpret_cast<intptr_t>(p)); 40551b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 4056c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (space->identity() == CODE_SPACE) { 4057c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST>(space, p, NULL); 4058c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 4059c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(space, p, NULL); 4060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 40611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org pages_swept++; 4062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 4063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com default: { 4065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UNREACHABLE(); 4066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 406843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 406943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 40701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (FLAG_gc_verbose) { 40711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org PrintF("SweepSpace: %s (%d pages swept)\n", 40721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org AllocationSpaceName(space->identity()), 40731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org pages_swept); 40741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 40751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 4076c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Give pages that are queued to be freed back to the OS. 4077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap()->FreeQueuedChunks(); 407843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 407943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 408043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::SweepSpaces() { 4082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); 408343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG 4084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com state_ = SWEEP_SPACES; 408543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 4086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SweeperType how_to_sweep = 4087c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; 40882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE; 40892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE; 409064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (FLAG_expose_gc) how_to_sweep = CONSERVATIVE; 4091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (sweep_precisely_) how_to_sweep = PRECISE; 40926e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 40936e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // Unlink evacuation candidates before sweeper threads access the list of 40946e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // pages to avoid race condition. 40956e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org UnlinkEvacuationCandidates(); 40966e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 4097c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Noncompacting collections simply sweep the spaces to clear the mark 4098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // bits and free the nonlive blocks (for old and map spaces). We sweep 4099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the map space last because freeing non-live maps overwrites them and 4100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the other spaces rely on possibly non-live maps to get the sizes for 4101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // non-live objects. 4102750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org SequentialSweepingScope scope(this); 4103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SweepSpace(heap()->old_pointer_space(), how_to_sweep); 4104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SweepSpace(heap()->old_data_space(), how_to_sweep); 410543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (how_to_sweep == PARALLEL_CONSERVATIVE || 41072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org how_to_sweep == CONCURRENT_CONSERVATIVE) { 41087c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // TODO(hpayer): fix race with concurrent sweeper 41097c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org StartSweeperThreads(); 41102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org } 41112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org 41122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org if (how_to_sweep == PARALLEL_CONSERVATIVE) { 41132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org WaitUntilSweepingCompleted(); 41147c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org } 41157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 4116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RemoveDeadInvalidatedCode(); 4117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SweepSpace(heap()->code_space(), PRECISE); 411843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SweepSpace(heap()->cell_space(), PRECISE); 412041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org SweepSpace(heap()->property_cell_space(), PRECISE); 412143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org EvacuateNewSpaceAndCandidates(); 412343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // ClearNonLiveTransitions depends on precise sweeping of map space to 4125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // detect whether unmarked map became dead in this collection or in one 4126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of the previous ones. 4127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SweepSpace(heap()->map_space(), PRECISE); 412843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Deallocate unmarked objects and clear marked bits for marked objects. 4130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_->lo_space()->FreeUnmarkedObjects(); 41312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org 41326e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // Deallocate evacuated candidate pages. 41336e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org ReleaseEvacuationCandidates(); 413443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 413543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 413643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EnableCodeFlushing(bool enable) { 4138e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 4139876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org if (isolate()->debug()->IsLoaded() || 4140876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org isolate()->debug()->has_break_points()) { 4141e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org enable = false; 4142e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org } 4143e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org#endif 4144e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org 4145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (enable) { 4146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (code_flusher_ != NULL) return; 4147876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org code_flusher_ = new CodeFlusher(isolate()); 4148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 4149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (code_flusher_ == NULL) return; 4150e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org code_flusher_->EvictAllCandidates(); 4151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com delete code_flusher_; 4152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com code_flusher_ = NULL; 415343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 41544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 41554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (FLAG_trace_code_flushing) { 41564e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org PrintF("[code-flushing is now %s]\n", enable ? "on" : "off"); 41574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org } 415843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 415943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 416043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// TODO(1466) ReportDeleteIfNeeded is not called currently. 4162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Our profiling tools do not expect intersections between 4163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// code objects. We should either reenable it or change our tools. 4164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj, 4165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Isolate* isolate) { 4166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef ENABLE_GDB_JIT_INTERFACE 4167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (obj->IsCode()) { 4168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GDBJITInterface::RemoveCode(reinterpret_cast<Code*>(obj)); 416943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 417043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 4171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (obj->IsCode()) { 4172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PROFILE(isolate, CodeDeleteEvent(obj->address())); 4173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 417443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 417543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 417643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4177876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.orgIsolate* MarkCompactCollector::isolate() const { 4178876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org return heap_->isolate(); 4179876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org} 4180876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org 4181876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org 4182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::Initialize() { 4183b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org MarkCompactMarkingVisitor::Initialize(); 4184b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org IncrementalMarking::Initialize(); 4185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 418643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 418743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool SlotsBuffer::IsTypedSlot(ObjectSlot slot) { 4189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return reinterpret_cast<uintptr_t>(slot) < NUMBER_OF_SLOT_TYPES; 4190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 419143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 419243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool SlotsBuffer::AddTo(SlotsBufferAllocator* allocator, 4194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer** buffer_address, 4195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotType type, 4196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address addr, 4197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AdditionMode mode) { 4198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer* buffer = *buffer_address; 4199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (buffer == NULL || !buffer->HasSpaceForTypedSlot()) { 4200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mode == FAIL_ON_OVERFLOW && ChainLengthThresholdReached(buffer)) { 4201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com allocator->DeallocateChain(buffer_address); 4202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return false; 420330ce411529579186181838984710b0b0980857aaricow@chromium.org } 4204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com buffer = allocator->AllocateBuffer(buffer); 4205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *buffer_address = buffer; 42069258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } 4207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(buffer->HasSpaceForTypedSlot()); 4208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com buffer->Add(reinterpret_cast<ObjectSlot>(type)); 4209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com buffer->Add(reinterpret_cast<ObjectSlot>(addr)); 4210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return true; 4211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 421243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42139258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 4214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { 4215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (RelocInfo::IsCodeTarget(rmode)) { 4216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return SlotsBuffer::CODE_TARGET_SLOT; 4217b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } else if (RelocInfo::IsEmbeddedObject(rmode)) { 4218b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org return SlotsBuffer::EMBEDDED_OBJECT_SLOT; 4219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (RelocInfo::IsDebugBreakSlot(rmode)) { 4220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return SlotsBuffer::DEBUG_TARGET_SLOT; 4221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (RelocInfo::IsJSReturn(rmode)) { 4222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return SlotsBuffer::JS_RETURN_SLOT; 4223b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UNREACHABLE(); 4225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return SlotsBuffer::NUMBER_OF_SLOT_TYPES; 42269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org} 42279258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 42289258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 4229b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgvoid MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { 4230b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); 4231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (target_page->IsEvacuationCandidate() && 4232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (rinfo->host() == NULL || 4233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { 4234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, 4235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com target_page->slots_buffer_address(), 4236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotTypeForRMode(rinfo->rmode()), 4237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com rinfo->pc(), 4238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::FAIL_ON_OVERFLOW)) { 4239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EvictEvacuationCandidate(target_page); 4240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 42429258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org} 42439258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 42449258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 4245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { 4246b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); 4247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (target_page->IsEvacuationCandidate() && 4248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) { 4249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, 4250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com target_page->slots_buffer_address(), 4251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::CODE_ENTRY_SLOT, 4252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com slot, 4253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::FAIL_ON_OVERFLOW)) { 4254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EvictEvacuationCandidate(target_page); 4255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 42579258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org} 42589258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 42599258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 426033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgvoid MarkCompactCollector::RecordCodeTargetPatch(Address pc, Code* target) { 426133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ASSERT(heap()->gc_state() == Heap::MARK_COMPACT); 426233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (is_compacting()) { 4263876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org Code* host = isolate()->inner_pointer_to_code_cache()-> 426433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org GcSafeFindCodeForInnerPointer(pc); 426533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org MarkBit mark_bit = Marking::MarkBitFrom(host); 426633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (Marking::IsBlack(mark_bit)) { 426733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); 426833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org RecordRelocSlot(&rinfo, target); 426933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 427033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 427133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org} 427233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 427333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 4274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline SlotsBuffer::SlotType DecodeSlotType( 4275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer::ObjectSlot slot) { 4276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return static_cast<SlotsBuffer::SlotType>(reinterpret_cast<intptr_t>(slot)); 4277defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org} 4278defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 4279defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 4280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid SlotsBuffer::UpdateSlots(Heap* heap) { 4281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PointersUpdatingVisitor v(heap); 428243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) { 4284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ObjectSlot slot = slots_[slot_idx]; 4285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!IsTypedSlot(slot)) { 4286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PointersUpdatingVisitor::UpdateSlot(heap, slot); 4287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 4288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ++slot_idx; 4289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(slot_idx < idx_); 4290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UpdateSlot(&v, 4291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DecodeSlotType(slot), 4292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com reinterpret_cast<Address>(slots_[slot_idx])); 4293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 429443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 429543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 429643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 429743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid SlotsBuffer::UpdateSlotsWithFilter(Heap* heap) { 4299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PointersUpdatingVisitor v(heap); 4300b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) { 4302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ObjectSlot slot = slots_[slot_idx]; 4303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!IsTypedSlot(slot)) { 4304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!IsOnInvalidatedCodeObject(reinterpret_cast<Address>(slot))) { 4305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PointersUpdatingVisitor::UpdateSlot(heap, slot); 4306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 4308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ++slot_idx; 4309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(slot_idx < idx_); 4310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address pc = reinterpret_cast<Address>(slots_[slot_idx]); 4311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!IsOnInvalidatedCodeObject(pc)) { 4312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UpdateSlot(&v, 4313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DecodeSlotType(slot), 4314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com reinterpret_cast<Address>(slots_[slot_idx])); 4315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4317ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 4318ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 4319ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 4320ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 4321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comSlotsBuffer* SlotsBufferAllocator::AllocateBuffer(SlotsBuffer* next_buffer) { 4322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return new SlotsBuffer(next_buffer); 4323b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4324b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4325ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 4326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid SlotsBufferAllocator::DeallocateBuffer(SlotsBuffer* buffer) { 4327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com delete buffer; 43284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 43294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 43304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 4331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid SlotsBufferAllocator::DeallocateChain(SlotsBuffer** buffer_address) { 4332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer* buffer = *buffer_address; 4333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com while (buffer != NULL) { 4334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer* next_buffer = buffer->next(); 4335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DeallocateBuffer(buffer); 4336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com buffer = next_buffer; 4337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com *buffer_address = NULL; 4339ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org} 4340ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 4341ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 434243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 4343