13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "code-stubs.h" 31756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#include "compilation-cache.h" 323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "deoptimizer.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "execution.h" 34b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "gdb-jit.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "global-handles.h" 363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "heap-profiler.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ic-inl.h" 383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "incremental-marking.h" 391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "liveobjectlist-inl.h" 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "mark-compact.h" 41756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#include "objects-visiting.h" 423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "objects-visiting-inl.h" 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "stub-cache.h" 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst char* Marking::kWhiteBitPattern = "00"; 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst char* Marking::kBlackBitPattern = "10"; 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst char* Marking::kGreyBitPattern = "11"; 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst char* Marking::kImpossibleBitPattern = "01"; 533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------- 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// MarkCompactCollector 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockMarkCompactCollector::MarkCompactCollector() : // NOLINT 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block state_(IDLE), 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch sweep_precisely_(false), 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reduce_memory_footprint_(false), 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch abort_incremental_marking_(false), 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compacting_(false), 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch was_marked_incrementally_(false), 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collect_maps_(FLAG_collect_maps), 683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flush_monomorphic_ics_(false), 6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block tracer_(NULL), 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch migration_slots_buffer_(NULL), 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block heap_(NULL), 7269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch code_flusher_(NULL), 7369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch encountered_weak_maps_(NULL) { } 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 75756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass VerifyMarkingVisitor: public ObjectVisitor { 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void VisitPointers(Object** start, Object** end) { 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (Object** current = start; current < end; current++) { 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((*current)->IsHeapObject()) { 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* object = HeapObject::cast(*current); 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(HEAP->mark_compact_collector()->IsMarked(object)); 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void VerifyMarking(Address bottom, Address top) { 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarkingVisitor visitor; 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* object; 933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address next_object_must_be_here_or_later = bottom; 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (Address current = bottom; 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current < top; 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current += kPointerSize) { 983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object = HeapObject::FromAddress(current); 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (MarkCompactCollector::IsMarked(object)) { 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(current >= next_object_must_be_here_or_later); 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object->Iterate(&visitor); 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch next_object_must_be_here_or_later = current + object->Size(); 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void VerifyMarking(NewSpace* space) { 1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address end = space->top(); 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpacePageIterator it(space->bottom(), end); 1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The bottom position is at the start of its page. Allows us to use 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // page->area_start() as start of range on all pages. 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(space->bottom(), 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpacePage::FromAddress(space->bottom())->area_start()); 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpacePage* page = it.next(); 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address limit = it.has_next() ? page->area_end() : end; 1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(limit == end || !page->Contains(end)); 1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarking(page->area_start(), limit); 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void VerifyMarking(PagedSpace* space) { 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PageIterator it(space); 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = it.next(); 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarking(p->area_start(), p->area_end()); 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void VerifyMarking(Heap* heap) { 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarking(heap->old_pointer_space()); 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarking(heap->old_data_space()); 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarking(heap->code_space()); 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarking(heap->cell_space()); 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarking(heap->map_space()); 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarking(heap->new_space()); 1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarkingVisitor visitor; 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LargeObjectIterator it(heap->lo_space()); 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (MarkCompactCollector::IsMarked(obj)) { 1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj->Iterate(&visitor); 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass VerifyEvacuationVisitor: public ObjectVisitor { 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void VisitPointers(Object** start, Object** end) { 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (Object** current = start; current < end; current++) { 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((*current)->IsHeapObject()) { 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* object = HeapObject::cast(*current); 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void VerifyEvacuation(Address bottom, Address top) { 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuationVisitor visitor; 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* object; 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address next_object_must_be_here_or_later = bottom; 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (Address current = bottom; 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current < top; 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current += kPointerSize) { 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object = HeapObject::FromAddress(current); 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (MarkCompactCollector::IsMarked(object)) { 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(current >= next_object_must_be_here_or_later); 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object->Iterate(&visitor); 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch next_object_must_be_here_or_later = current + object->Size(); 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void VerifyEvacuation(NewSpace* space) { 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpacePageIterator it(space->bottom(), space->top()); 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuationVisitor visitor; 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpacePage* page = it.next(); 1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address current = page->area_start(); 1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address limit = it.has_next() ? page->area_end() : space->top(); 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(limit == space->top() || !page->Contains(space->top())); 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (current < limit) { 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* object = HeapObject::FromAddress(current); 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object->Iterate(&visitor); 1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current += object->Size(); 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void VerifyEvacuation(PagedSpace* space) { 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PageIterator it(space); 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = it.next(); 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (p->IsEvacuationCandidate()) continue; 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuation(p->area_start(), p->area_end()); 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void VerifyEvacuation(Heap* heap) { 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuation(heap->old_pointer_space()); 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuation(heap->old_data_space()); 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuation(heap->code_space()); 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuation(heap->cell_space()); 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuation(heap->map_space()); 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuation(heap->new_space()); 2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuationVisitor visitor; 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->IterateStrongRoots(&visitor, VISIT_ALL); 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::AddEvacuationCandidate(Page* p) { 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->MarkEvacuationCandidate(); 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch evacuation_candidates_.Add(p); 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void TraceFragmentation(PagedSpace* space) { 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int number_of_pages = space->CountTotalPages(); 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t reserved = (number_of_pages * space->AreaSize()); 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t free = reserved - space->SizeOfObjects(); 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("[%s]: %d pages, %d (%.1f%%) free\n", 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllocationSpaceName(space->identity()), 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch number_of_pages, 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(free), 2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<double>(free) * 100 / reserved); 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool MarkCompactCollector::StartCompaction(CompactionMode mode) { 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!compacting_) { 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(evacuation_candidates_.length() == 0); 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CollectEvacuationCandidates(heap()->old_pointer_space()); 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CollectEvacuationCandidates(heap()->old_data_space()); 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_compact_code_space && mode == NON_INCREMENTAL_COMPACTION) { 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CollectEvacuationCandidates(heap()->code_space()); 2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (FLAG_trace_fragmentation) { 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TraceFragmentation(heap()->code_space()); 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_fragmentation) { 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TraceFragmentation(heap()->map_space()); 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TraceFragmentation(heap()->cell_space()); 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists(); 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->old_data_space()->EvictEvacuationCandidatesFromFreeLists(); 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compacting_ = evacuation_candidates_.length() > 0; 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return compacting_; 2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::CollectGarbage() { 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that Prepare() has been called. The individual steps below will 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // update the state as they proceed. 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(state_ == PREPARE_GC); 28069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(encountered_weak_maps_ == Smi::FromInt(0)); 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MarkLiveObjects(); 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(heap_->incremental_marking()->IsStopped()); 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (collect_maps_) ClearNonLiveTransitions(); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ClearWeakMaps(); 28869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_verify_heap) { 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarking(heap_); 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 294592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepSpaces(); 2965d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!collect_maps_) ReattachInitialMaps(); 2985d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->isolate()->inner_pointer_to_code_cache()->Flush(); 300592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 30185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch Finish(); 302592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 30385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch tracer_ = NULL; 304592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 305592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 306592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PageIterator it(space); 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = it.next(); 3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(p->markbits()->IsClean()); 3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(0, p->LiveBytes()); 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) { 3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpacePageIterator it(space->bottom(), space->top()); 3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpacePage* p = it.next(); 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(p->markbits()->IsClean()); 3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(0, p->LiveBytes()); 3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::VerifyMarkbitsAreClean() { 3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarkbitsAreClean(heap_->old_pointer_space()); 3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarkbitsAreClean(heap_->old_data_space()); 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarkbitsAreClean(heap_->code_space()); 3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarkbitsAreClean(heap_->cell_space()); 3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarkbitsAreClean(heap_->map_space()); 3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarkbitsAreClean(heap_->new_space()); 3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LargeObjectIterator it(heap_->lo_space()); 3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark_bit = Marking::MarkBitFrom(obj); 3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Marking::IsWhite(mark_bit)); 3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void ClearMarkbitsInPagedSpace(PagedSpace* space) { 3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PageIterator it(space); 3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::Clear(it.next()); 3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void ClearMarkbitsInNewSpace(NewSpace* space) { 3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); 3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::Clear(it.next()); 3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::ClearMarkbits() { 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ClearMarkbitsInPagedSpace(heap_->code_space()); 3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ClearMarkbitsInPagedSpace(heap_->map_space()); 3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ClearMarkbitsInPagedSpace(heap_->old_pointer_space()); 3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ClearMarkbitsInPagedSpace(heap_->old_data_space()); 3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ClearMarkbitsInPagedSpace(heap_->cell_space()); 3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ClearMarkbitsInNewSpace(heap_->new_space()); 3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LargeObjectIterator it(heap_->lo_space()); 3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark_bit = Marking::MarkBitFrom(obj); 3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mark_bit.Clear(); 3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mark_bit.Next().Clear(); 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Marking::TransferMark(Address old_start, Address new_start) { 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This is only used when resizing an object. 3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(MemoryChunk::FromAddress(old_start) == 3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk::FromAddress(new_start)); 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the mark doesn't move, we don't check the color of the object. 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // It doesn't matter whether the object is black, since it hasn't changed 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // size, so the adjustment to the live data count will be zero anyway. 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (old_start == new_start) return false; 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit new_mark_bit = MarkBitFrom(new_start); 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit old_mark_bit = MarkBitFrom(old_start); 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectColor old_color = Color(old_mark_bit); 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Marking::IsBlack(old_mark_bit)) { 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch old_mark_bit.Clear(); 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IsWhite(old_mark_bit)); 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Marking::MarkBlack(new_mark_bit); 4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return true; 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (Marking::IsGrey(old_mark_bit)) { 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(heap_->incremental_marking()->IsMarking()); 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch old_mark_bit.Clear(); 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch old_mark_bit.Next().Clear(); 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IsWhite(old_mark_bit)); 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->incremental_marking()->WhiteToGreyAndPush( 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::FromAddress(new_start), new_mark_bit); 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->incremental_marking()->RestartIfNotMarking(); 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectColor new_color = Color(new_mark_bit); 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(new_color == old_color); 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return false; 4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst char* AllocationSpaceName(AllocationSpace space) { 4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (space) { 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case NEW_SPACE: return "NEW_SPACE"; 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case OLD_POINTER_SPACE: return "OLD_POINTER_SPACE"; 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case OLD_DATA_SPACE: return "OLD_DATA_SPACE"; 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CODE_SPACE: return "CODE_SPACE"; 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case MAP_SPACE: return "MAP_SPACE"; 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CELL_SPACE: return "CELL_SPACE"; 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case LO_SPACE: return "LO_SPACE"; 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Returns zero for pages that have so little fragmentation that it is not 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// worth defragmenting them. Otherwise a positive integer that gives an 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// estimate of fragmentation on an arbitrary scale. 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic int FreeListFragmentation(PagedSpace* space, Page* p) { 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If page was not swept then there are no free list items on it. 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!p->WasSwept()) { 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_fragmentation) { 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("%p [%s]: %d bytes live (unswept)\n", 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<void*>(p), 4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllocationSpaceName(space->identity()), 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->LiveBytes()); 4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 0; 4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FreeList::SizeStats sizes; 4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->CountFreeListItems(p, &sizes); 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t ratio; 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t ratio_threshold; 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t area_size = space->AreaSize(); 4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (space->identity() == CODE_SPACE) { 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch area_size; 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ratio_threshold = 10; 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch area_size; 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ratio_threshold = 15; 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_fragmentation) { 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("%p [%s]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<void*>(p), 4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllocationSpaceName(space->identity()), 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(sizes.small_size_), 4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<double>(sizes.small_size_ * 100) / 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch area_size, 4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(sizes.medium_size_), 4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<double>(sizes.medium_size_ * 100) / 4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch area_size, 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(sizes.large_size_), 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<double>(sizes.large_size_ * 100) / 4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch area_size, 4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(sizes.huge_size_), 4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<double>(sizes.huge_size_ * 100) / 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch area_size, 4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (ratio > ratio_threshold) ? "[fragmented]" : ""); 4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_always_compact && sizes.Total() != area_size) { 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 1; 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (ratio <= ratio_threshold) return 0; // Not fragmented. 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return static_cast<int>(ratio - ratio_threshold); 4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(space->identity() == OLD_POINTER_SPACE || 5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->identity() == OLD_DATA_SPACE || 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->identity() == CODE_SPACE); 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int number_of_pages = space->CountTotalPages(); 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const int kMaxMaxEvacuationCandidates = 1000; 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int max_evacuation_candidates = Min( 5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kMaxMaxEvacuationCandidates, 5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(sqrt(static_cast<double>(number_of_pages / 2)) + 1)); 5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_stress_compaction || FLAG_always_compact) { 5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch max_evacuation_candidates = kMaxMaxEvacuationCandidates; 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class Candidate { 5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Candidate() : fragmentation_(0), page_(NULL) { } 5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Candidate(int f, Page* p) : fragmentation_(f), page_(p) { } 5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int fragmentation() { return fragmentation_; } 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* page() { return page_; } 5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int fragmentation_; 5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* page_; 5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum CompactionMode { 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch COMPACT_FREE_LISTS, 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch REDUCE_MEMORY_FOOTPRINT 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompactionMode mode = COMPACT_FREE_LISTS; 5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t reserved = number_of_pages * space->AreaSize(); 5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t over_reserved = reserved - space->SizeOfObjects(); 5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const intptr_t kFreenessThreshold = 50; 5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (over_reserved >= 2 * space->AreaSize() && 5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reduce_memory_footprint_) { 5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mode = REDUCE_MEMORY_FOOTPRINT; 5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We expect that empty pages are easier to compact so slightly bump the 5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // limit. 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch max_evacuation_candidates += 2; 5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_fragmentation) { 5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Estimated over reserved memory: %.1f MB (setting threshold %d)\n", 5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<double>(over_reserved) / MB, 5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(kFreenessThreshold)); 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t estimated_release = 0; 5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Candidate candidates[kMaxMaxEvacuationCandidates]; 5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int count = 0; 5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int fragmentation = 0; 5593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Candidate* least = NULL; 5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PageIterator it(space); 5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (it.has_next()) it.next(); // Never compact the first page. 5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = it.next(); 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ClearEvacuationCandidate(); 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_stress_compaction) { 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int counter = space->heap()->ms_count(); 5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uintptr_t page_number = reinterpret_cast<uintptr_t>(p) >> kPageSizeBits; 5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((counter & 1) == (page_number & 1)) fragmentation = 1; 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (mode == REDUCE_MEMORY_FOOTPRINT) { 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Don't try to release too many pages. 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (estimated_release >= ((over_reserved * 3) / 4)) { 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch continue; 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t free_bytes = 0; 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!p->WasSwept()) { 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch free_bytes = (p->area_size() - p->LiveBytes()); 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FreeList::SizeStats sizes; 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->CountFreeListItems(p, &sizes); 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch free_bytes = sizes.Total(); 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int free_pct = static_cast<int>(free_bytes * 100) / p->area_size(); 5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (free_pct >= kFreenessThreshold) { 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch estimated_release += 2 * p->area_size() - free_bytes; 5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fragmentation = free_pct; 5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fragmentation = 0; 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_fragmentation) { 5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("%p [%s]: %d (%.2f%%) free %s\n", 5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<void*>(p), 6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllocationSpaceName(space->identity()), 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(free_bytes), 6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<double>(free_bytes * 100) / p->area_size(), 6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (fragmentation > 0) ? "[fragmented]" : ""); 6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fragmentation = FreeListFragmentation(space, p); 6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fragmentation != 0) { 6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (count < max_evacuation_candidates) { 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch candidates[count++] = Candidate(fragmentation, p); 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (least == NULL) { 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < max_evacuation_candidates; i++) { 6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (least == NULL || 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch candidates[i].fragmentation() < least->fragmentation()) { 6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch least = candidates + i; 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (least->fragmentation() < fragmentation) { 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *least = Candidate(fragmentation, p); 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch least = NULL; 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < count; i++) { 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AddEvacuationCandidate(candidates[i].page()); 6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (count > 0 && FLAG_trace_fragmentation) { 6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Collected %d evacuation candidates for space %s\n", 6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch count, 6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllocationSpaceName(space->identity())); 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::AbortCompaction() { 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (compacting_) { 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int npages = evacuation_candidates_.length(); 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < npages; i++) { 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = evacuation_candidates_[i]; 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ClearEvacuationCandidate(); 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compacting_ = false; 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch evacuation_candidates_.Rewind(0); 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch invalidated_code_.Rewind(0); 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(0, evacuation_candidates_.length()); 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::Prepare(GCTracer* tracer) { 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch was_marked_incrementally_ = heap()->incremental_marking()->IsMarking(); 6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Disable collection of maps if incremental marking is enabled. 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Map collection algorithm relies on a special map transition tree traversal 6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // order which is not implemented for incremental marking. 6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collect_maps_ = FLAG_collect_maps && !was_marked_incrementally_; 6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Monomorphic ICs are preserved when possible, but need to be flushed 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // when they might be keeping a Context alive, or when the heap is about 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to be serialized. 6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flush_monomorphic_ics_ = 6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->isolate()->context_exit_happened() || Serializer::enabled(); 6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Rather than passing the tracer around we stash it in a static member 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // variable. 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tracer_ = tracer; 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(state_ == IDLE); 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block state_ = PREPARE_GC; 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!FLAG_never_compact || !FLAG_always_compact); 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (collect_maps_) CreateBackPointers(); 684b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 685b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (FLAG_gdbjit) { 686b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // If GDBJIT interface is active disable compaction. 687b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch compacting_collection_ = false; 688b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 689b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clear marking bits if incremental marking is aborted. 6923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (was_marked_incrementally_ && abort_incremental_marking_) { 6933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->incremental_marking()->Abort(); 6943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ClearMarkbits(); 6953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AbortCompaction(); 6963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch was_marked_incrementally_ = false; 6973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Don't start compaction if we are in the middle of incremental 7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // marking cycle. We did not collect any slots. 7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!FLAG_never_compact && !was_marked_incrementally_) { 7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StartCompaction(NON_INCREMENTAL_COMPACTION); 7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PagedSpaces spaces; 706d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (PagedSpace* space = spaces.next(); 7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space != NULL; 7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space = spaces.next()) { 7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->PrepareForMarkCompact(); 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!was_marked_incrementally_ && FLAG_verify_heap) { 7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyMarkbitsAreClean(); 7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::Finish() { 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 7227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT(state_ == SWEEP_SPACES || state_ == RELOCATE_OBJECTS); 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block state_ = IDLE; 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The stub cache is not traversed during GC; clear the cache to 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // force lazy re-initialization of it. This must be done after the 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GC, because it relies on the new address of certain old space 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // objects (empty string, illegal builtin). 7298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->stub_cache()->Clear(); 730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->external_string_table_.CleanUp(); 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------- 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Phase 1: tracing and marking live objects. 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// before: all objects are in normal state. 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// after: a live object's map pointer is marked as '00'. 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Marking all live objects in the heap as part of mark-sweep or mark-compact 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// collection. Before marking, all objects are in their normal state. After 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// marking, live objects' map pointers are marked indicating that the object 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// has been found reachable. 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The marking algorithm is a (mostly) depth-first (because of possible stack 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// overflow) traversal of the graph of objects reachable from the roots. It 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// uses an explicit stack of pointers rather than recursion. The young 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// generation's inactive ('from') space is used as a marking stack. The 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// objects in the marking stack are the ones that have been reached and marked 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// but their children have not yet been visited. 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The marking stack can overflow during traversal. In that case, we set an 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// overflow flag. When the overflow flag is set, we continue marking objects 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// reachable from the objects on the marking stack, but no longer push them on 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the marking stack. Instead, we mark them as both marked and overflowed. 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// When the stack is in the overflowed state, objects marked as overflowed 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// have been reached and marked but their children have not been visited yet. 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// After emptying the marking stack, we clear the overflow flag and traverse 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the heap looking for objects marked as overflowed, push them on the stack, 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and continue with marking. This process repeats until all reachable 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// objects have been marked. 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 76344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass CodeFlusher { 764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 76544f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit CodeFlusher(Isolate* isolate) 76644f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(isolate), 76744f0eee88ff00398ff7f715fab053374d808c90dSteve Block jsfunction_candidates_head_(NULL), 76844f0eee88ff00398ff7f715fab053374d808c90dSteve Block shared_function_info_candidates_head_(NULL) {} 76944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 77044f0eee88ff00398ff7f715fab053374d808c90dSteve Block void AddCandidate(SharedFunctionInfo* shared_info) { 771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetNextCandidate(shared_info, shared_function_info_candidates_head_); 772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared_function_info_candidates_head_ = shared_info; 773b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 77544f0eee88ff00398ff7f715fab053374d808c90dSteve Block void AddCandidate(JSFunction* function) { 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(function->code() == function->shared()->code()); 777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 778b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetNextCandidate(function, jsfunction_candidates_head_); 779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch jsfunction_candidates_head_ = function; 780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 78244f0eee88ff00398ff7f715fab053374d808c90dSteve Block void ProcessCandidates() { 783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ProcessSharedFunctionInfoCandidates(); 784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ProcessJSFunctionCandidates(); 785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 78844f0eee88ff00398ff7f715fab053374d808c90dSteve Block void ProcessJSFunctionCandidates() { 78944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); 790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* candidate = jsfunction_candidates_head_; 792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* next_candidate; 793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (candidate != NULL) { 794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch next_candidate = GetNextCandidate(candidate); 795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SharedFunctionInfo* shared = candidate->shared(); 797b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = shared->code(); 7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit code_mark = Marking::MarkBitFrom(code); 8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!code_mark.Get()) { 801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->set_code(lazy_compile); 802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch candidate->set_code(lazy_compile); 803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch candidate->set_code(shared->code()); 805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 806b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We are in the middle of a GC cycle so the write barrier in the code 8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // setter did not record the slot update and we have to do that manually. 8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address slot = candidate->address() + JSFunction::kCodeEntryOffset; 8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot)); 8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->heap()->mark_compact_collector()-> 8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordCodeEntrySlot(slot, target); 8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSharedFunctionInfoCodeSlot(shared); 8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch candidate = next_candidate; 817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch jsfunction_candidates_head_ = NULL; 820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 82344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void ProcessSharedFunctionInfoCandidates() { 82444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); 825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 826b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SharedFunctionInfo* candidate = shared_function_info_candidates_head_; 827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SharedFunctionInfo* next_candidate; 828b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (candidate != NULL) { 829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch next_candidate = GetNextCandidate(candidate); 830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetNextCandidate(candidate, NULL); 831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = candidate->code(); 8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit code_mark = Marking::MarkBitFrom(code); 8343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!code_mark.Get()) { 835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch candidate->set_code(lazy_compile); 836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSharedFunctionInfoCodeSlot(candidate); 8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 840b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch candidate = next_candidate; 841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 843b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared_function_info_candidates_head_ = NULL; 844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void RecordSharedFunctionInfoCodeSlot(SharedFunctionInfo* shared) { 8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** slot = HeapObject::RawField(shared, 8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SharedFunctionInfo::kCodeOffset); 8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->heap()->mark_compact_collector()-> 8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSlot(slot, slot, HeapObject::cast(*slot)); 8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static JSFunction** GetNextCandidateField(JSFunction* candidate) { 854b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return reinterpret_cast<JSFunction**>( 855b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch candidate->address() + JSFunction::kCodeEntryOffset); 856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 858b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static JSFunction* GetNextCandidate(JSFunction* candidate) { 859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return *GetNextCandidateField(candidate); 860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void SetNextCandidate(JSFunction* candidate, 863b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* next_candidate) { 864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *GetNextCandidateField(candidate) = next_candidate; 865b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static SharedFunctionInfo** GetNextCandidateField( 868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SharedFunctionInfo* candidate) { 8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = candidate->code(); 870b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return reinterpret_cast<SharedFunctionInfo**>( 8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->address() + Code::kGCMetadataOffset); 872b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 873b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 874b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) { 8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return reinterpret_cast<SharedFunctionInfo*>( 8763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch candidate->code()->gc_metadata()); 877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 879b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void SetNextCandidate(SharedFunctionInfo* candidate, 880b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SharedFunctionInfo* next_candidate) { 8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch candidate->code()->set_gc_metadata(next_candidate); 882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 883b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 88444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 88544f0eee88ff00398ff7f715fab053374d808c90dSteve Block JSFunction* jsfunction_candidates_head_; 88644f0eee88ff00398ff7f715fab053374d808c90dSteve Block SharedFunctionInfo* shared_function_info_candidates_head_; 887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 88844f0eee88ff00398ff7f715fab053374d808c90dSteve Block DISALLOW_COPY_AND_ASSIGN(CodeFlusher); 889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 89244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockMarkCompactCollector::~MarkCompactCollector() { 89344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (code_flusher_ != NULL) { 89444f0eee88ff00398ff7f715fab053374d808c90dSteve Block delete code_flusher_; 89544f0eee88ff00398ff7f715fab053374d808c90dSteve Block code_flusher_ = NULL; 89644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 89744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 89844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline HeapObject* ShortCircuitConsString(Object** p) { 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Optimization: If the heap object pointed to by p is a non-symbol 90244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // cons string whose right substring is HEAP->empty_string, update 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // it in place to its left substring. Return the updated value. 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Here we assume that if we change *p, we replace it with a heap object 9063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // (i.e., the left substring of a cons string is always a heap object). 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The check performed is: 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object->IsConsString() && !object->IsSymbol() && 91044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // (ConsString::cast(object)->second() == HEAP->empty_string()) 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // except the maps for the object and its possible substrings might be 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // marked. 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject* object = HeapObject::cast(*p); 9143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!FLAG_clever_optimizations) return object; 9153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* map = object->map(); 9163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceType type = map->instance_type(); 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object; 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* second = reinterpret_cast<ConsString*>(object)->unchecked_second(); 9203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = map->GetHeap(); 9213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (second != heap->empty_string()) { 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return object; 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Since we don't have the object's start, it is impossible to update the 9267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // page dirty marks. Therefore, we only replace the string with its left 9277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // substring when page dirty marks do not change. 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* first = reinterpret_cast<ConsString*>(object)->unchecked_first(); 92944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!heap->InNewSpace(object) && heap->InNewSpace(first)) return object; 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p = first; 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return HeapObject::cast(first); 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 936756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass StaticMarkingVisitor : public StaticVisitorBase { 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 938756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static inline void IterateBody(Map* map, HeapObject* obj) { 939756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.GetVisitor(map)(map, obj); 940756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 941756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 942756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static void Initialize() { 943756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitShortcutCandidate, 944756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick &FixedBodyVisitor<StaticMarkingVisitor, 945756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ConsString::BodyDescriptor, 946756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void>::Visit); 947756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 948756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitConsString, 949756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick &FixedBodyVisitor<StaticMarkingVisitor, 950756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ConsString::BodyDescriptor, 951756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void>::Visit); 952756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 95369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch table_.Register(kVisitSlicedString, 95469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch &FixedBodyVisitor<StaticMarkingVisitor, 95569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SlicedString::BodyDescriptor, 95669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void>::Visit); 957756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 958756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitFixedArray, 959756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick &FlexibleBodyVisitor<StaticMarkingVisitor, 960756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick FixedArray::BodyDescriptor, 961756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void>::Visit); 962756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 9633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch table_.Register(kVisitGlobalContext, &VisitGlobalContext); 964f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 9653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch table_.Register(kVisitFixedDoubleArray, DataObjectVisitor::Visit); 96685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 967756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitByteArray, &DataObjectVisitor::Visit); 9683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit); 969756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit); 970756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit); 971756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 97269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch table_.Register(kVisitJSWeakMap, &VisitJSWeakMap); 97369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 974756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitOddball, 975756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick &FixedBodyVisitor<StaticMarkingVisitor, 976756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Oddball::BodyDescriptor, 977756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void>::Visit); 978756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitMap, 979756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick &FixedBodyVisitor<StaticMarkingVisitor, 980756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Map::BodyDescriptor, 981756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void>::Visit); 982756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 983756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitCode, &VisitCode); 984756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch table_.Register(kVisitSharedFunctionInfo, 986b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &VisitSharedFunctionInfoAndFlushCode); 987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch table_.Register(kVisitJSFunction, 989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &VisitJSFunctionAndFlushCode); 990756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 991257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch table_.Register(kVisitJSRegExp, 992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch &VisitRegExpAndFlushCode); 993257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 994756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.Register(kVisitPropertyCell, 995756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick &FixedBodyVisitor<StaticMarkingVisitor, 996756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick JSGlobalPropertyCell::BodyDescriptor, 997756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void>::Visit); 998756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 999756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.RegisterSpecializations<DataObjectVisitor, 1000756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kVisitDataObject, 1001756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kVisitDataObjectGeneric>(); 1002756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1003756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.RegisterSpecializations<JSObjectVisitor, 1004756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kVisitJSObject, 1005756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kVisitJSObjectGeneric>(); 1006756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1007756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick table_.RegisterSpecializations<StructObjectVisitor, 1008756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kVisitStruct, 1009756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick kVisitStructGeneric>(); 1010756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1011756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 101244f0eee88ff00398ff7f715fab053374d808c90dSteve Block INLINE(static void VisitPointer(Heap* heap, Object** p)) { 10133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObjectByPointer(heap->mark_compact_collector(), p, p); 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101644f0eee88ff00398ff7f715fab053374d808c90dSteve Block INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) { 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark all objects pointed to in [start, end). 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kMinRangeForMarkingRecursion = 64; 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (end - start >= kMinRangeForMarkingRecursion) { 102044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (VisitUnmarkedObjects(heap, start, end)) return; 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We are close to a stack overflow, so just mark the objects. 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 10233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkCompactCollector* collector = heap->mark_compact_collector(); 10243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (Object** p = start; p < end; p++) { 10253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObjectByPointer(collector, start, p); 102685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 102785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 102885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 102985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) { 103085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); 10313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSGlobalPropertyCell* cell = 10323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSGlobalPropertyCell::cast(rinfo->target_cell()); 10333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(cell); 10343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->MarkObject(cell, mark); 10353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo) { 10383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); 10393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(mstarzinger): We do not short-circuit cons strings here, verify 10403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // that there can be no such embedded pointers and add assertion here. 10413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* object = HeapObject::cast(rinfo->target_object()); 10423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->RecordRelocSlot(rinfo, object); 10433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(object); 10443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->MarkObject(object, mark); 10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { 10483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); 10493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); 10503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub() 10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch && (target->ic_state() == MEGAMORPHIC || 10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->flush_monomorphic_ics_ || 10533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target->ic_age() != heap->global_ic_age())) { 10543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IC::Clear(rinfo->pc()); 10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target = Code::GetCodeFromTargetAddress(rinfo->target_address()); 1056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit code_mark = Marking::MarkBitFrom(target); 10583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->MarkObject(target, code_mark); 10593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->RecordRelocSlot(rinfo, target); 1060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1061b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) { 10637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && 10647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch rinfo->IsPatchedReturnSequence()) || 10657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 10667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch rinfo->IsPatchedDebugBreakSlotSequence())); 10673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); 10683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit code_mark = Marking::MarkBitFrom(target); 10693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->MarkObject(target, code_mark); 10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->RecordRelocSlot(rinfo, target); 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark object pointed to by p. 10743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, 10753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** anchor_slot, 10763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** p)) { 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!(*p)->IsHeapObject()) return; 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject* object = ShortCircuitConsString(p); 10793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector->RecordSlot(anchor_slot, p, object); 10803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(object); 10813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector->MarkObject(object, mark); 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 108444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Visit an unmarked object. 10868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, 10878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HeapObject* obj)) { 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 10898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(Isolate::Current()->heap()->Contains(obj)); 10903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!HEAP->mark_compact_collector()->IsMarked(obj)); 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* map = obj->map(); 10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = obj->GetHeap(); 10943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(obj); 10953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->SetMark(obj, mark); 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark the map pointer and the body. 10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit map_mark = Marking::MarkBitFrom(map); 10983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->MarkObject(map, map_mark); 1099756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick IterateBody(map, obj); 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Visit all unmarked objects pointed to by [start, end). 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns false if the operation fails (lack of stack space). 110444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static inline bool VisitUnmarkedObjects(Heap* heap, 110544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object** start, 110644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object** end) { 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return false is we are close to the stack limit. 110844f0eee88ff00398ff7f715fab053374d808c90dSteve Block StackLimitCheck check(heap->isolate()); 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (check.HasOverflowed()) return false; 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MarkCompactCollector* collector = heap->mark_compact_collector(); 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Visit the unmarked objects. 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (Object** p = start; p < end; p++) { 11143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* o = *p; 11153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!o->IsHeapObject()) continue; 11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector->RecordSlot(start, p, o); 11173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* obj = HeapObject::cast(o); 11183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(obj); 11193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mark.Get()) continue; 11208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch VisitUnmarkedObject(collector, obj); 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1124756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1125756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static inline void VisitExternalReference(Address* p) { } 11263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline void VisitExternalReference(RelocInfo* rinfo) { } 1127756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static inline void VisitRuntimeEntry(RelocInfo* rinfo) { } 1128756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1129756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick private: 1130756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick class DataObjectVisitor { 1131756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick public: 1132756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick template<int size> 1133756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static void VisitSpecialized(Map* map, HeapObject* object) { 1134756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1135756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1136756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static void Visit(Map* map, HeapObject* object) { 1137756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1138756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick }; 1139756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1140756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick typedef FlexibleBodyVisitor<StaticMarkingVisitor, 1141756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick JSObject::BodyDescriptor, 1142756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void> JSObjectVisitor; 1143756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1144756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick typedef FlexibleBodyVisitor<StaticMarkingVisitor, 1145756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick StructBodyDescriptor, 1146756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void> StructObjectVisitor; 1147756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 114869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static void VisitJSWeakMap(Map* map, HeapObject* object) { 11493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); 115069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(object); 115169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 115269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Enqueue weak map in linked list of encountered weak maps. 115369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(weak_map->next() == Smi::FromInt(0)); 115469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch weak_map->set_next(collector->encountered_weak_maps()); 115569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch collector->set_encountered_weak_maps(weak_map); 115669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 115769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Skip visiting the backing hash table containing the mappings. 115869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object); 115969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch BodyVisitorBase<StaticMarkingVisitor>::IteratePointers( 11603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map->GetHeap(), 116169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch object, 116269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSWeakMap::BodyDescriptor::kStartOffset, 116369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSWeakMap::kTableOffset); 116469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch BodyVisitorBase<StaticMarkingVisitor>::IteratePointers( 11653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map->GetHeap(), 116669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch object, 116769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSWeakMap::kTableOffset + kPointerSize, 116869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch object_size); 116969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 117069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Mark the backing hash table without pushing it on the marking stack. 11713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectHashTable* table = ObjectHashTable::cast(weak_map->table()); 11723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!MarkCompactCollector::IsMarked(table)); 11733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector->SetMark(table, Marking::MarkBitFrom(table)); 11743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector->MarkObject(table->map(), Marking::MarkBitFrom(table->map())); 11753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(MarkCompactCollector::IsMarked(table->map())); 117669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 117769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1178756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static void VisitCode(Map* map, HeapObject* object) { 11793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = map->GetHeap(); 11803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = reinterpret_cast<Code*>(object); 11813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_cleanup_code_caches_at_gc) { 11823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* raw_info = code->type_feedback_info(); 11833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_info->IsTypeFeedbackInfo()) { 11843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TypeFeedbackCells* type_feedback_cells = 11853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TypeFeedbackInfo::cast(raw_info)->type_feedback_cells(); 11863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < type_feedback_cells->CellCount(); i++) { 11873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(type_feedback_cells->AstId(i)->IsSmi()); 11883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSGlobalPropertyCell* cell = type_feedback_cells->Cell(i); 11893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap)); 11903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->CodeIterateBody<StaticMarkingVisitor>(heap); 1194756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1195756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1196756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Code flushing support. 1197756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1198756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // How many collections newly compiled code object will survive before being 1199756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // flushed. 1200756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static const int kCodeAgeThreshold = 5; 1201756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1202257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kRegExpCodeThreshold = 5; 1203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 12048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) { 12053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* undefined = heap->undefined_value(); 1206756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return (info->script() != undefined) && 1207756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick (reinterpret_cast<Script*>(info->script())->source() != undefined); 1208756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1209756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1210756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1211756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick inline static bool IsCompiled(JSFunction* function) { 12123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return function->code() != 12138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); 1214756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1215756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1216756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick inline static bool IsCompiled(SharedFunctionInfo* function) { 12173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return function->code() != 12188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); 1219756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1220756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 12218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline static bool IsFlushable(Heap* heap, JSFunction* function) { 1222756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick SharedFunctionInfo* shared_info = function->unchecked_shared(); 1223756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Code is either on stack, in compilation cache or referenced 1225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // by optimized version of function. 12263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit code_mark = Marking::MarkBitFrom(function->code()); 12273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (code_mark.Get()) { 12283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!Marking::MarkBitFrom(shared_info).Get()) { 12293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shared_info->set_code_age(0); 12303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 1232756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1233756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We do not flush code for optimized functions. 12353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (function->code() != shared_info->code()) { 1236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 1237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12398b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return IsFlushable(heap, shared_info); 1240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 12428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch inline static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info) { 1243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Code is either on stack, in compilation cache or referenced 1244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // by optimized version of function. 12453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit code_mark = 12463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Marking::MarkBitFrom(shared_info->code()); 12473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (code_mark.Get()) { 1248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 1249756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1250756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1251756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // The function must be compiled and have the source code available, 1252756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // to be able to recompile it in case we need the function again. 12538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) { 1254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 1255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1256756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1257756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // We never flush code for Api functions. 1258756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Object* function_data = shared_info->function_data(); 12593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (function_data->IsFunctionTemplateInfo()) { 1260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 1261756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1262756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1263756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Only flush code for functions. 1264692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch if (shared_info->code()->kind() != Code::FUNCTION) { 1265692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch return false; 1266692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch } 1267756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1268756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Function must be lazy compilable. 1269692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch if (!shared_info->allows_lazy_compilation()) { 1270692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch return false; 1271692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch } 1272756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1273756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // If this is a full script wrapped in a function we do no flush the code. 1274692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch if (shared_info->is_toplevel()) { 1275692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch return false; 1276692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch } 1277756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1278756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Age this shared function info. 1279756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (shared_info->code_age() < kCodeAgeThreshold) { 1280756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick shared_info->set_code_age(shared_info->code_age() + 1); 1281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 1282756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1283756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 1285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 128844f0eee88ff00398ff7f715fab053374d808c90dSteve Block static bool FlushCodeForFunction(Heap* heap, JSFunction* function) { 12898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (!IsFlushable(heap, function)) return false; 1290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // This function's code looks flushable. But we have to postpone the 1292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // decision until we see all functions that point to the same 1293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // SharedFunctionInfo because some of them might be optimized. 1294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // That would make the nonoptimized version of the code nonflushable, 1295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // because it is required for bailing out from optimized code. 129644f0eee88ff00398ff7f715fab053374d808c90dSteve Block heap->mark_compact_collector()->code_flusher()->AddCandidate(function); 1297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 1298756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1299756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1300756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static inline bool IsValidNotBuiltinContext(Object* ctx) { 13013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ctx->IsContext() && 13023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !Context::cast(ctx)->global()->IsJSBuiltinsObject(); 1303756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1304756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1305756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void VisitSharedFunctionInfoGeneric(Map* map, HeapObject* object) { 13070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object); 1308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap(); 1310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FixedBodyVisitor<StaticMarkingVisitor, 13120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen SharedFunctionInfo::BodyDescriptor, 13130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen void>::Visit(map, object); 13140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 13150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 13160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void UpdateRegExpCodeAgeAndFlush(Heap* heap, 1318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JSRegExp* re, 1319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool is_ascii) { 1320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Make sure that the fixed array is in fact initialized on the RegExp. 1321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We could potentially trigger a GC when initializing the RegExp. 13223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (HeapObject::cast(re->data())->map()->instance_type() != 13233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FIXED_ARRAY_TYPE) return; 1324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Make sure this is a RegExp that actually contains code. 1326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (re->TypeTagUnchecked() != JSRegExp::IRREGEXP) return; 1327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Object* code = re->DataAtUnchecked(JSRegExp::code_index(is_ascii)); 13293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!code->IsSmi() && 13303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::cast(code)->map()->instance_type() == CODE_TYPE) { 1331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Save a copy that can be reinstated if we need the code again. 1332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii), 1333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code, 1334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch heap); 13353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Saving a copy might create a pointer into compaction candidate 13373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // that was not observed by marker. This might happen if JSRegExp data 13383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // was marked through the compilation cache before marker reached JSRegExp 13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // object. 13403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* data = FixedArray::cast(re->data()); 13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** slot = data->data_start() + JSRegExp::saved_code_index(is_ascii); 13423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()-> 13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSlot(slot, slot, code); 13443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1345257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Set a number in the 0-255 range to guarantee no smi overflow. 1346257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii), 1347257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Smi::FromInt(heap->sweep_generation() & 0xff), 1348257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch heap); 1349257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (code->IsSmi()) { 1350257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int value = Smi::cast(code)->value(); 1351257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // The regexp has not been compiled yet or there was a compilation error. 1352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (value == JSRegExp::kUninitializedValue || 1353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch value == JSRegExp::kCompilationErrorValue) { 1354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 1355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check if we should flush now. 1358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (value == ((heap->sweep_generation() - kRegExpCodeThreshold) & 0xff)) { 1359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii), 1360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Smi::FromInt(JSRegExp::kUninitializedValue), 1361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch heap); 1362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii), 1363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Smi::FromInt(JSRegExp::kUninitializedValue), 1364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch heap); 1365257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Works by setting the current sweep_generation (as a smi) in the 1371257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // code object place in the data array of the RegExp and keeps a copy 1372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // around that can be reinstated if we reuse the RegExp before flushing. 1373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If we did not use the code for kRegExpCodeThreshold mark sweep GCs 1374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // we flush the code. 1375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void VisitRegExpAndFlushCode(Map* map, HeapObject* object) { 13763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = map->GetHeap(); 1377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch MarkCompactCollector* collector = heap->mark_compact_collector(); 1378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!collector->is_code_flushing_enabled()) { 1379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch VisitJSRegExpFields(map, object); 1380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 1381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JSRegExp* re = reinterpret_cast<JSRegExp*>(object); 13833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Flush code or set age on both ASCII and two byte code. 1384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UpdateRegExpCodeAgeAndFlush(heap, re, true); 1385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UpdateRegExpCodeAgeAndFlush(heap, re, false); 1386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Visit the fields of the RegExp, including the updated FixedArray. 1387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch VisitJSRegExpFields(map, object); 1388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void VisitSharedFunctionInfoAndFlushCode(Map* map, 1392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HeapObject* object) { 13933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); 139444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!collector->is_code_flushing_enabled()) { 139544f0eee88ff00398ff7f715fab053374d808c90dSteve Block VisitSharedFunctionInfoGeneric(map, object); 139644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 139744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VisitSharedFunctionInfoAndFlushCodeGeneric(map, object, false); 1399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void VisitSharedFunctionInfoAndFlushCodeGeneric( 1403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Map* map, HeapObject* object, bool known_flush_code_candidate) { 14043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = map->GetHeap(); 1405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object); 1406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap(); 1408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 14098f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch if (shared->ic_age() != heap->global_ic_age()) { 14108f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch shared->ResetForNewContext(heap->global_ic_age()); 14118f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch } 14128f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch 1413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!known_flush_code_candidate) { 14148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch known_flush_code_candidate = IsFlushable(heap, shared); 141544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (known_flush_code_candidate) { 141644f0eee88ff00398ff7f715fab053374d808c90dSteve Block heap->mark_compact_collector()->code_flusher()->AddCandidate(shared); 141744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 142044f0eee88ff00398ff7f715fab053374d808c90dSteve Block VisitSharedFunctionInfoFields(heap, object, known_flush_code_candidate); 1421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 142444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static void VisitCodeEntry(Heap* heap, Address entry_address) { 14253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); 14263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(code); 14273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->MarkObject(code, mark); 14283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()-> 14293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordCodeEntrySlot(entry_address, code); 1430592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1431791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 14323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void VisitGlobalContext(Map* map, HeapObject* object) { 14333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedBodyVisitor<StaticMarkingVisitor, 14343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Context::MarkCompactBodyDescriptor, 14353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void>::Visit(map, object); 14363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); 14383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int idx = Context::FIRST_WEAK_SLOT; 14393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch idx < Context::GLOBAL_CONTEXT_SLOTS; 14403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ++idx) { 14413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** slot = 14423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::RawField(object, FixedArray::OffsetOfElementAt(idx)); 14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector->RecordSlot(slot, slot, *slot); 14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 144685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 1447791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { 14483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = map->GetHeap(); 144944f0eee88ff00398ff7f715fab053374d808c90dSteve Block MarkCompactCollector* collector = heap->mark_compact_collector(); 145044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!collector->is_code_flushing_enabled()) { 145144f0eee88ff00398ff7f715fab053374d808c90dSteve Block VisitJSFunction(map, object); 145244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 145344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 145444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1455791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); 1456756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // The function must have a valid context and not be a builtin. 1457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool flush_code_candidate = false; 1458756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { 145944f0eee88ff00398ff7f715fab053374d808c90dSteve Block flush_code_candidate = FlushCodeForFunction(heap, jsfunction); 1460756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!flush_code_candidate) { 14633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = jsfunction->shared()->code(); 14643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit code_mark = Marking::MarkBitFrom(code); 14653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector->MarkObject(code, code_mark); 1466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 14673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (jsfunction->code()->kind() == Code::OPTIMIZED_FUNCTION) { 14683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector->MarkInlinedFunctionsCode(jsfunction->code()); 1469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VisitJSFunctionFields(map, 1473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<JSFunction*>(object), 1474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch flush_code_candidate); 1475791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block } 1476791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 1477791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 1478791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block static void VisitJSFunction(Map* map, HeapObject* object) { 1479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VisitJSFunctionFields(map, 1480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<JSFunction*>(object), 1481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch false); 1482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define SLOT_ADDR(obj, offset) \ 1486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<Object**>((obj)->address() + offset) 1487756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static inline void VisitJSFunctionFields(Map* map, 1490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* object, 1491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool flush_code_candidate) { 14923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = map->GetHeap(); 149344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 149444f0eee88ff00398ff7f715fab053374d808c90dSteve Block VisitPointers(heap, 14953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::RawField(object, JSFunction::kPropertiesOffset), 14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::RawField(object, JSFunction::kCodeEntryOffset)); 1497791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 1498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!flush_code_candidate) { 149944f0eee88ff00398ff7f715fab053374d808c90dSteve Block VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset); 1500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 1501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Don't visit code object. 1502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Visit shared function info to avoid double checking of it's 1504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // flushability. 1505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SharedFunctionInfo* shared_info = object->unchecked_shared(); 15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit shared_info_mark = Marking::MarkBitFrom(shared_info); 15073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!shared_info_mark.Get()) { 1508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Map* shared_info_map = shared_info->map(); 15093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit shared_info_map_mark = 15103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Marking::MarkBitFrom(shared_info_map); 15113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->SetMark(shared_info, shared_info_mark); 15123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->MarkObject(shared_info_map, 15133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shared_info_map_mark); 1514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map, 1515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared_info, 1516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch true); 1517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1519791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 15203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitPointers( 15213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap, 15223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::RawField(object, 15233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSFunction::kCodeEntryOffset + kPointerSize), 15243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::RawField(object, 15253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSFunction::kNonWeakFieldsEndOffset)); 1526f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Don't visit the next function list field as it is a weak reference. 15283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** next_function = 15293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::RawField(object, JSFunction::kNextFunctionLinkOffset); 15303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->mark_compact_collector()->RecordSlot( 15313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch next_function, next_function, *next_function); 1532756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1533756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1534257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static inline void VisitJSRegExpFields(Map* map, 1535257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HeapObject* object) { 1536257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int last_property_offset = 1537257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JSRegExp::kSize + kPointerSize * map->inobject_properties(); 15383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitPointers(map->GetHeap(), 1539257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SLOT_ADDR(object, JSRegExp::kPropertiesOffset), 1540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SLOT_ADDR(object, last_property_offset)); 1541257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1542257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1543791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 154444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static void VisitSharedFunctionInfoFields(Heap* heap, 154544f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapObject* object, 1546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool flush_code_candidate) { 154744f0eee88ff00398ff7f715fab053374d808c90dSteve Block VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kNameOffset)); 1548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!flush_code_candidate) { 155044f0eee88ff00398ff7f715fab053374d808c90dSteve Block VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kCodeOffset)); 1551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 155344f0eee88ff00398ff7f715fab053374d808c90dSteve Block VisitPointers(heap, 155444f0eee88ff00398ff7f715fab053374d808c90dSteve Block SLOT_ADDR(object, SharedFunctionInfo::kScopeInfoOffset), 1555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SLOT_ADDR(object, SharedFunctionInfo::kSize)); 1556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 1557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch #undef SLOT_ADDR 1559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1560756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick typedef void (*Callback)(Map* map, HeapObject* object); 1561756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1562756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static VisitorDispatchTable<Callback> table_; 1563756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}; 1564756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1565756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1566756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickVisitorDispatchTable<StaticMarkingVisitor::Callback> 1567756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick StaticMarkingVisitor::table_; 1568756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1569756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1570756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass MarkingVisitor : public ObjectVisitor { 1571756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick public: 157244f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit MarkingVisitor(Heap* heap) : heap_(heap) { } 157344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1574756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void VisitPointer(Object** p) { 157544f0eee88ff00398ff7f715fab053374d808c90dSteve Block StaticMarkingVisitor::VisitPointer(heap_, p); 1576756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1577756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1578756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void VisitPointers(Object** start, Object** end) { 157944f0eee88ff00398ff7f715fab053374d808c90dSteve Block StaticMarkingVisitor::VisitPointers(heap_, start, end); 1580756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1581756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 158244f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 158344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Heap* heap_; 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1587756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass CodeMarkingVisitor : public ThreadVisitor { 1588756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick public: 158944f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit CodeMarkingVisitor(MarkCompactCollector* collector) 159044f0eee88ff00398ff7f715fab053374d808c90dSteve Block : collector_(collector) {} 159144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 15928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 1593692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch collector_->PrepareThreadForCodeFlushing(isolate, top); 1594756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 159544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 159644f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 159744f0eee88ff00398ff7f715fab053374d808c90dSteve Block MarkCompactCollector* collector_; 1598756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}; 1599756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1600756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1601756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickclass SharedFunctionInfoMarkingVisitor : public ObjectVisitor { 1602756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick public: 160344f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) 160444f0eee88ff00398ff7f715fab053374d808c90dSteve Block : collector_(collector) {} 160544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1606756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void VisitPointers(Object** start, Object** end) { 1607756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick for (Object** p = start; p < end; p++) VisitPointer(p); 1608756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1609756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1610756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick void VisitPointer(Object** slot) { 1611756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Object* obj = *slot; 1612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (obj->IsSharedFunctionInfo()) { 1613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); 16143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit shared_mark = Marking::MarkBitFrom(shared); 16153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit code_mark = Marking::MarkBitFrom(shared->code()); 16163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector_->MarkObject(shared->code(), code_mark); 16173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector_->MarkObject(shared, shared_mark); 1618756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1619756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 162044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 162144f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 162244f0eee88ff00398ff7f715fab053374d808c90dSteve Block MarkCompactCollector* collector_; 1623756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}; 1624756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1625756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1626692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdochvoid MarkCompactCollector::MarkInlinedFunctionsCode(Code* code) { 1627692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // For optimized functions we should retain both non-optimized version 1628692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // of it's code and non-optimized version of all inlined functions. 1629692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // This is required to support bailing out from inlined code. 1630692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch DeoptimizationInputData* data = 16313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizationInputData::cast(code->deoptimization_data()); 1632692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 16333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* literals = data->LiteralArray(); 1634692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 1635692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch for (int i = 0, count = data->InlinedFunctionCount()->value(); 1636692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch i < count; 1637692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch i++) { 16383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSFunction* inlined = JSFunction::cast(literals->get(i)); 16393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* inlined_code = inlined->shared()->code(); 16403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit inlined_code_mark = Marking::MarkBitFrom(inlined_code); 16413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObject(inlined_code, inlined_code_mark); 1642692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch } 1643692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch} 1644692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 1645692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 1646692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdochvoid MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate, 1647692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch ThreadLocalTop* top) { 1648692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { 1649692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // Note: for the frame that has a pending lazy deoptimization 1650692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // StackFrame::unchecked_code will return a non-optimized code object for 1651692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // the outermost function and StackFrame::LookupCode will return 1652692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch // actual optimized code object. 1653692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch StackFrame* frame = it.frame(); 1654692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch Code* code = frame->unchecked_code(); 16553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit code_mark = Marking::MarkBitFrom(code); 16563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObject(code, code_mark); 1657692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch if (frame->is_optimized()) { 1658692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch MarkInlinedFunctionsCode(frame->LookupCode()); 1659692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch } 1660692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch } 1661692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch} 1662692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 1663692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 1664756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid MarkCompactCollector::PrepareForCodeFlushing() { 16658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(heap() == Isolate::Current()->heap()); 166644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 16673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(1609) Currently incremental marker does not support code flushing. 16683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!FLAG_flush_code || was_marked_incrementally_) { 166944f0eee88ff00398ff7f715fab053374d808c90dSteve Block EnableCodeFlushing(false); 1670756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return; 1671756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1672756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1673756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#ifdef ENABLE_DEBUGGER_SUPPORT 16748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (heap()->isolate()->debug()->IsLoaded() || 16758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->debug()->has_break_points()) { 167644f0eee88ff00398ff7f715fab053374d808c90dSteve Block EnableCodeFlushing(false); 1677756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return; 1678756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 1679756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#endif 16803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 168144f0eee88ff00398ff7f715fab053374d808c90dSteve Block EnableCodeFlushing(true); 1682756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 16839ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick // Ensure that empty descriptor array is marked. Method MarkDescriptorArray 16849ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick // relies on it being marked before any other descriptor array. 16853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* descriptor_array = heap()->empty_descriptor_array(); 16863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit descriptor_array_mark = Marking::MarkBitFrom(descriptor_array); 16873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObject(descriptor_array, descriptor_array_mark); 16889ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick 1689756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Make sure we are not referencing the code from the stack. 16908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(this == heap()->mark_compact_collector()); 1691692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch PrepareThreadForCodeFlushing(heap()->isolate(), 1692692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch heap()->isolate()->thread_local_top()); 1693756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1694756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Iterate the archived stacks in all threads to check if 1695756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // the code is referenced. 169644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeMarkingVisitor code_marking_visitor(this); 16978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->thread_manager()->IterateArchivedThreads( 169844f0eee88ff00398ff7f715fab053374d808c90dSteve Block &code_marking_visitor); 1699756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 170044f0eee88ff00398ff7f715fab053374d808c90dSteve Block SharedFunctionInfoMarkingVisitor visitor(this); 17018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->compilation_cache()->IterateFunctions(&visitor); 17028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->handle_scope_implementer()->Iterate(&visitor); 1703756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 17043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ProcessMarkingDeque(); 1705756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 1706756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1707756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Visitor class for marking heap roots. 1709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RootMarkingVisitor : public ObjectVisitor { 1710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 171144f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit RootMarkingVisitor(Heap* heap) 171244f0eee88ff00398ff7f715fab053374d808c90dSteve Block : collector_(heap->mark_compact_collector()) { } 171344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void VisitPointer(Object** p) { 1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MarkObjectByPointer(p); 1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void VisitPointers(Object** start, Object** end) { 1719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (Object** p = start; p < end; p++) MarkObjectByPointer(p); 1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void MarkObjectByPointer(Object** p) { 1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!(*p)->IsHeapObject()) return; 1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Replace flat cons strings in place. 1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject* object = ShortCircuitConsString(p); 17283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark_bit = Marking::MarkBitFrom(object); 17293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mark_bit.Get()) return; 1730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* map = object->map(); 1732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark the object. 17333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector_->SetMark(object, mark_bit); 1734756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark the map pointer and body, and push them on the marking stack. 17363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit map_mark = Marking::MarkBitFrom(map); 17373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector_->MarkObject(map, map_mark); 1738756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick StaticMarkingVisitor::IterateBody(map, object); 1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark all the objects reachable from the map and body. May leave 1741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // overflowed objects in the heap. 17423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch collector_->EmptyMarkingDeque(); 1743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 174444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 174544f0eee88ff00398ff7f715fab053374d808c90dSteve Block MarkCompactCollector* collector_; 1746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 1747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class for pruning the symbol table. 1750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SymbolTableCleaner : public ObjectVisitor { 1751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 17528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit SymbolTableCleaner(Heap* heap) 17538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : heap_(heap), pointers_removed_(0) { } 1754e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1755e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke virtual void VisitPointers(Object** start, Object** end) { 1756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Visit all HeapObject pointers in [start, end). 1757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (Object** p = start; p < end; p++) { 17583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* o = *p; 17593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (o->IsHeapObject() && 17603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !Marking::MarkBitFrom(HeapObject::cast(o)).Get()) { 1761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if the symbol being pruned is an external symbol. We need to 1762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // delete the associated external data as this symbol is going away. 1763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Since no objects have yet been moved we can safely access the map of 1765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the object. 17663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (o->IsExternalString()) { 17678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap_->FinalizeExternalString(String::cast(*p)); 1768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 17693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set the entry to the_hole_value (as deleted). 17703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *p = heap_->the_hole_value(); 1771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pointers_removed_++; 1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int PointersRemoved() { 1777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return pointers_removed_; 1778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 17793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 17818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Heap* heap_; 1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pointers_removed_; 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1786f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch// Implementation of WeakObjectRetainer for mark compact GCs. All marked objects 1787f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch// are retained. 1788f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochclass MarkCompactWeakObjectRetainer : public WeakObjectRetainer { 1789f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch public: 1790f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch virtual Object* RetainAs(Object* object) { 17913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Marking::MarkBitFrom(HeapObject::cast(object)).Get()) { 1792f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return object; 1793f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else { 1794f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return NULL; 1795f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 1796f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 1797f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}; 1798f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1799f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 18003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::ProcessNewlyMarkedObject(HeapObject* object) { 18013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IsMarked(object)); 180244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(HEAP->Contains(object)); 1803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsMap()) { 1804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* map = Map::cast(object); 18053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->ClearCacheOnMap(map); 18063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 18073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // When map collection is enabled we have to mark through map's transitions 18083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // in a special way to make transition links weak. 18093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Only maps for subclasses of JSReceiver can have transitions. 18103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 18113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (collect_maps_ && map->instance_type() >= FIRST_JS_RECEIVER_TYPE) { 1812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MarkMapContents(map); 1813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 18143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque_.PushBlack(map); 1815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 18173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque_.PushBlack(object); 1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::MarkMapContents(Map* map) { 1823053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // Mark prototype transitions array but don't push it into marking stack. 1824053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // This will make references from it weak. We will clean dead prototype 1825053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block // transitions in ClearNonLiveTransitions. 18263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* prototype_transitions = map->prototype_transitions(); 18273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(prototype_transitions); 18283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!mark.Get()) { 18293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mark.Set(); 18303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk::IncrementLiveBytesFromGC(prototype_transitions->address(), 18313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch prototype_transitions->Size()); 18323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1833053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 18343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** raw_descriptor_array_slot = 18353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset); 18363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* raw_descriptor_array = *raw_descriptor_array_slot; 1837257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!raw_descriptor_array->IsSmi()) { 1838257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch MarkDescriptorArray( 1839257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch reinterpret_cast<DescriptorArray*>(raw_descriptor_array)); 1840257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark the Object* fields of the Map. 1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Since the descriptor array has been marked already, it is fine 1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that one of these fields contains a pointer to it. 1845756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Object** start_slot = HeapObject::RawField(map, 1846756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Map::kPointerFieldsBeginOffset); 1847756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 1848756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset); 1849756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 18503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticMarkingVisitor::VisitPointers(map->GetHeap(), start_slot, end_slot); 18513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 18523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::MarkAccessorPairSlot(HeapObject* accessors, 18553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset) { 18563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** slot = HeapObject::RawField(accessors, offset); 18573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* accessor = HeapObject::cast(*slot); 18583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (accessor->IsMap()) return; 18593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSlot(slot, slot, accessor); 18603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObjectAndPush(accessor); 1861c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch} 1862c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 1863c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 1864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::MarkDescriptorArray( 1865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DescriptorArray* descriptors) { 18663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit descriptors_mark = Marking::MarkBitFrom(descriptors); 18673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (descriptors_mark.Get()) return; 1868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Empty descriptor array is marked as a root before any maps are marked. 18693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(descriptors != heap()->empty_descriptor_array()); 18703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetMark(descriptors, descriptors_mark); 1871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FixedArray* contents = reinterpret_cast<FixedArray*>( 1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block descriptors->get(DescriptorArray::kContentArrayIndex)); 1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(contents->IsHeapObject()); 18753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!IsMarked(contents)); 1876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(contents->IsFixedArray()); 1877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(contents->length() >= 2); 18783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit contents_mark = Marking::MarkBitFrom(contents); 18793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetMark(contents, contents_mark); 188044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Contents contains (value, details) pairs. If the details say that the type 188144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION, 188244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // EXTERNAL_ARRAY_TRANSITION or NULL_DESCRIPTOR, we don't mark the value as 188344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // live. Only for MAP_TRANSITION, EXTERNAL_ARRAY_TRANSITION and 188444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // CONSTANT_TRANSITION is the value an Object* (a Map*). 1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < contents->length(); i += 2) { 1886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the pair (value, details) at index i, i+1 is not 1887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a transition or null descriptor, mark the value. 1888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PropertyDetails details(Smi::cast(contents->get(i + 1))); 18893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** slot = contents->data_start() + i; 18913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!(*slot)->IsHeapObject()) continue; 18923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* value = HeapObject::cast(*slot); 18933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSlot(slot, slot, *slot); 18953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (details.type()) { 18973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case NORMAL: 18983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FIELD: 18993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CONSTANT_FUNCTION: 19003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case HANDLER: 19013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case INTERCEPTOR: 19023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObjectAndPush(value); 19033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 19043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CALLBACKS: 19053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!value->IsAccessorPair()) { 19063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObjectAndPush(value); 19073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (!MarkObjectWithoutPush(value)) { 19083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkAccessorPairSlot(value, AccessorPair::kGetterOffset); 19093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkAccessorPairSlot(value, AccessorPair::kSetterOffset); 19103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 19113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 19123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case ELEMENTS_TRANSITION: 19133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For maps with multiple elements transitions, the transition maps are 19143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // stored in a FixedArray. Keep the fixed array alive but not the maps 19153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // that it refers to. 19163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (value->IsFixedArray()) MarkObjectWithoutPush(value); 19173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 19183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case MAP_TRANSITION: 19193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CONSTANT_TRANSITION: 19203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case NULL_DESCRIPTOR: 19213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The DescriptorArray descriptors contains a pointer to its contents array, 1925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // but the contents array is already marked. 19263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque_.PushBlack(descriptors); 1927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::CreateBackPointers() { 19318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HeapObjectIterator iterator(heap()->map_space()); 19323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* next_object = iterator.Next(); 19333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch next_object != NULL; next_object = iterator.Next()) { 19343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (next_object->IsMap()) { // Could also be FreeSpace object on free list. 1935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* map = Map::cast(next_object); 19363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 19373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (map->instance_type() >= FIRST_JS_RECEIVER_TYPE) { 1938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block map->CreateBackPointers(); 1939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 19408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(map->instance_descriptors() == heap()->empty_descriptor_array()); 1941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Fill the marking stack with overflowed objects returned by the given 19483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// iterator. Stop when the marking stack is filled or the end of the space 19493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// is reached, whichever comes first. 19503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate<class T> 19513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void DiscoverGreyObjectsWithIterator(Heap* heap, 19523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkingDeque* marking_deque, 19533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch T* it) { 19543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The caller should ensure that the marking stack is initially not full, 19553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // so that we don't waste effort pointlessly scanning for objects. 19563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!marking_deque->IsFull()); 19573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* filler_map = heap->one_pointer_filler_map(); 19593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* object = it->Next(); 19603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object != NULL; 19613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object = it->Next()) { 19623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit markbit = Marking::MarkBitFrom(object); 19633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((object->map() != filler_map) && Marking::IsGrey(markbit)) { 19643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Marking::GreyToBlack(markbit); 19653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); 19663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque->PushBlack(object); 19673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque->IsFull()) return; 19683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 19693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1970592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 1971592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 1972592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 19733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts); 19743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, Page* p) { 19773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); 19783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 19793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); 19803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 19813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit::CellType* cells = p->markbits()->cells(); 19833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int last_cell_index = 19853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 19863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 19873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(p->area_end()))); 19883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address cell_base = p->area_start(); 19903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int cell_index = Bitmap::IndexToCell( 19913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 19923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(cell_base))); 19933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (; 19963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index < last_cell_index; 19973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index++, cell_base += 32 * kPointerSize) { 19983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((unsigned)cell_index == 19993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 20003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 20013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(cell_base)))); 20023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const MarkBit::CellType current_cell = cells[cell_index]; 20043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (current_cell == 0) continue; 20053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const MarkBit::CellType next_cell = cells[cell_index + 1]; 20073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit::CellType grey_objects = current_cell & 20083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ((current_cell >> 1) | (next_cell << (Bitmap::kBitsPerCell - 1))); 20093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset = 0; 20113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (grey_objects != 0) { 20123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(grey_objects); 20133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch grey_objects >>= trailing_zeros; 20143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch offset += trailing_zeros; 20153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit markbit(&cells[cell_index], 1 << offset, false); 20163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Marking::IsGrey(markbit)); 20173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Marking::GreyToBlack(markbit); 20183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address addr = cell_base + offset * kPointerSize; 20193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* object = HeapObject::FromAddress(addr); 20203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); 20213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque->PushBlack(object); 20223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque->IsFull()) return; 20233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch offset += 2; 20243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch grey_objects >>= 2; 2025592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 20263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch grey_objects >>= (Bitmap::kBitsPerCell - 1); 2028592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 20293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 20303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void DiscoverGreyObjectsInSpace(Heap* heap, 20333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkingDeque* marking_deque, 20343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PagedSpace* space) { 20353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!space->was_swept_conservatively()) { 20363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObjectIterator it(space); 20373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DiscoverGreyObjectsWithIterator(heap, marking_deque, &it); 20383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 20393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PageIterator it(space); 20403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 20413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = it.next(); 20423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DiscoverGreyObjectsOnPage(marking_deque, p); 20433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque->IsFull()) return; 20443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 20453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 20463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2047592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 2048592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 2049592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdochbool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { 20503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* o = *p; 20513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!o->IsHeapObject()) return false; 20523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* heap_object = HeapObject::cast(o); 20533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(heap_object); 20543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return !mark.Get(); 2055592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::MarkSymbolTable() { 20593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SymbolTable* symbol_table = heap()->symbol_table(); 2060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark the symbol table itself. 20613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit symbol_table_mark = Marking::MarkBitFrom(symbol_table); 20623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetMark(symbol_table, symbol_table_mark); 2063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Explicitly mark the prefix. 20648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MarkingVisitor marker(heap()); 2065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block symbol_table->IteratePrefix(&marker); 20663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ProcessMarkingDeque(); 2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { 2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark the heap roots including global variables, stack variables, 2072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // etc., and all objects reachable from them. 20738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); 2074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Handle the symbol table specially. 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MarkSymbolTable(); 2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // There may be overflowed objects in the heap. Visit them now. 20793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (marking_deque_.overflowed()) { 20803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RefillMarkingDeque(); 20813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmptyMarkingDeque(); 2082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::MarkObjectGroups() { 208744f0eee88ff00398ff7f715fab053374d808c90dSteve Block List<ObjectGroup*>* object_groups = 20888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->global_handles()->object_groups(); 2089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int last = 0; 2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < object_groups->length(); i++) { 2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ObjectGroup* entry = object_groups->at(i); 20938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(entry != NULL); 2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Object*** objects = entry->objects_; 2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool group_marked = false; 20978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch for (size_t j = 0; j < entry->length_; j++) { 2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* object = *objects[j]; 20993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (object->IsHeapObject()) { 21003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* heap_object = HeapObject::cast(object); 21013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(heap_object); 21023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mark.Get()) { 21033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch group_marked = true; 21043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 21053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (!group_marked) { 21108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch (*object_groups)[last++] = entry; 21118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch continue; 21128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 2113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // An object in the group is marked, so mark as grey all white heap 21153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // objects in the group. 21168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch for (size_t j = 0; j < entry->length_; ++j) { 21173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* object = *objects[j]; 21183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (object->IsHeapObject()) { 21193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* heap_object = HeapObject::cast(object); 21203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(heap_object); 21213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObject(heap_object, mark); 2122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 212444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 21253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Once the entire group has been colored grey, set the object group 21263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to NULL so it won't be processed again. 21278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch entry->Dispose(); 21283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object_groups->at(i) = NULL; 2129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 21308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch object_groups->Rewind(last); 2131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MarkCompactCollector::MarkImplicitRefGroups() { 213544f0eee88ff00398ff7f715fab053374d808c90dSteve Block List<ImplicitRefGroup*>* ref_groups = 21368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->global_handles()->implicit_ref_groups(); 213744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 21388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch int last = 0; 213944f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (int i = 0; i < ref_groups->length(); i++) { 214044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ImplicitRefGroup* entry = ref_groups->at(i); 21418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(entry != NULL); 214244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 21433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IsMarked(*entry->parent_)) { 21448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch (*ref_groups)[last++] = entry; 21458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch continue; 21468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 214744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 21488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Object*** children = entry->children_; 21498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // A parent object is marked, so mark all child heap objects. 21508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch for (size_t j = 0; j < entry->length_; ++j) { 215144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if ((*children[j])->IsHeapObject()) { 21523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* child = HeapObject::cast(*children[j]); 21533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark = Marking::MarkBitFrom(child); 21543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObject(child, mark); 215544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 215644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 215744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 21588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Once the entire group has been marked, dispose it because it's 21598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // not needed anymore. 21608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch entry->Dispose(); 216144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 21628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ref_groups->Rewind(last); 216344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 216444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 216544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Mark all objects reachable from the objects on the marking stack. 2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Before: the marking stack contains zero or more heap object pointers. 2168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// After: the marking stack is empty, and all objects reachable from the 2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// marking stack have been marked, or are overflowed in the heap. 21703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::EmptyMarkingDeque() { 21713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!marking_deque_.IsEmpty()) { 21723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!marking_deque_.IsEmpty()) { 21733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* object = marking_deque_.Pop(); 217469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(object->IsHeapObject()); 217569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(heap()->Contains(object)); 21763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); 217769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 21783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* map = object->map(); 21793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit map_mark = Marking::MarkBitFrom(map); 21803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObject(map, map_mark); 218169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 218269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StaticMarkingVisitor::IterateBody(map, object); 218369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 2184756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 218569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Process encountered weak maps, mark objects only reachable by those 218669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // weak maps and repeat until fix-point is reached. 218769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ProcessWeakMaps(); 2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sweep the heap for overflowed objects, clear their overflow bits, and 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// push them on the marking stack. Stop early if the marking stack fills 2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// before sweeping completes. If sweeping completes, there are no remaining 2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// overflowed objects in the heap so the overflow flag on the markings stack 2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// is cleared. 21973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::RefillMarkingDeque() { 21983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(marking_deque_.overflowed()); 21993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SemiSpaceIterator new_it(heap()->new_space()); 22013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &new_it); 22023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque_.IsFull()) return; 22033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DiscoverGreyObjectsInSpace(heap(), 22053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &marking_deque_, 22063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->old_pointer_space()); 22073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque_.IsFull()) return; 22083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DiscoverGreyObjectsInSpace(heap(), 22103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &marking_deque_, 22113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->old_data_space()); 22123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque_.IsFull()) return; 22133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DiscoverGreyObjectsInSpace(heap(), 22153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &marking_deque_, 22163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->code_space()); 22173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque_.IsFull()) return; 22183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DiscoverGreyObjectsInSpace(heap(), 22203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &marking_deque_, 22213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->map_space()); 22223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque_.IsFull()) return; 22233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DiscoverGreyObjectsInSpace(heap(), 22253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &marking_deque_, 22263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->cell_space()); 22273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque_.IsFull()) return; 22283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LargeObjectIterator lo_it(heap()->lo_space()); 22303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DiscoverGreyObjectsWithIterator(heap(), 22313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &marking_deque_, 22323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &lo_it); 22333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (marking_deque_.IsFull()) return; 22343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque_.ClearOverflowed(); 2236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Mark all objects reachable (transitively) from objects on the marking 2240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// stack. Before: the marking stack contains zero or more heap object 2241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// pointers. After: the marking stack is empty and there are no overflowed 2242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// objects in the heap. 22433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::ProcessMarkingDeque() { 22443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmptyMarkingDeque(); 22453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (marking_deque_.overflowed()) { 22463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RefillMarkingDeque(); 22473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmptyMarkingDeque(); 2248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 225244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MarkCompactCollector::ProcessExternalMarking() { 2253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool work_to_do = true; 22543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(marking_deque_.IsEmpty()); 2255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (work_to_do) { 2256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MarkObjectGroups(); 225744f0eee88ff00398ff7f715fab053374d808c90dSteve Block MarkImplicitRefGroups(); 22583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch work_to_do = !marking_deque_.IsEmpty(); 22593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ProcessMarkingDeque(); 2260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::MarkLiveObjects() { 2265f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); 2266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The recursive GC marker detects when it is nearing stack overflow, 2267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // and switches to a different marking system. JS interrupts interfere 2268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // with the C stack limit check. 22698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch PostponeInterruptsScope postpone(heap()->isolate()); 2270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 22713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool incremental_marking_overflowed = false; 22723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IncrementalMarking* incremental_marking = heap_->incremental_marking(); 22733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (was_marked_incrementally_) { 22743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Finalize the incremental marking and check whether we had an overflow. 22753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Both markers use grey color to mark overflowed objects so 22763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // non-incremental marker can deal with them as if overflow 22773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // occured during normal marking. 22783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // But incremental marker uses a separate marking deque 22793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // so we have to explicitly copy it's overflow state. 22803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch incremental_marking->Finalize(); 22813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch incremental_marking_overflowed = 22823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch incremental_marking->marking_deque()->overflowed(); 22833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch incremental_marking->marking_deque()->ClearOverflowed(); 22843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 22853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Abort any pending incremental activities e.g. incremental sweeping. 22863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch incremental_marking->Abort(); 22873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 22883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 2290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(state_ == PREPARE_GC); 2291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block state_ = MARK_LIVE_OBJECTS; 2292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 22933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The to space contains live objects, a page in from space is used as a 22943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // marking stack. 22953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address marking_deque_start = heap()->new_space()->FromSpacePageLow(); 22963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address marking_deque_end = heap()->new_space()->FromSpacePageHigh(); 22973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_force_marking_deque_overflows) { 22983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque_end = marking_deque_start + 64 * kPointerSize; 22993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque_.Initialize(marking_deque_start, 23013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque_end); 23023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!marking_deque_.overflowed()); 2303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (incremental_marking_overflowed) { 23053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // There are overflowed objects left in the heap after incremental marking. 23063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch marking_deque_.SetOverflowed(); 23073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2309756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick PrepareForCodeFlushing(); 2310756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 23113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (was_marked_incrementally_) { 23123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // There is no write barrier on cells so we have to scan them now at the end 23133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // of the incremental marking. 23143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 23153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObjectIterator cell_iterator(heap()->cell_space()); 23163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* cell; 23173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while ((cell = cell_iterator.Next()) != NULL) { 23183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(cell->IsJSGlobalPropertyCell()); 23193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IsMarked(cell)) { 23203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset = JSGlobalPropertyCell::kValueOffset; 23213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticMarkingVisitor::VisitPointer( 23223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap(), 23233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Object**>(cell->address() + offset)); 23243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch RootMarkingVisitor root_visitor(heap()); 2330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MarkRoots(&root_visitor); 2331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The objects reachable from the roots are marked, yet unreachable 233344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // objects are unmarked. Mark objects reachable due to host 233444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // application specific logic. 233544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ProcessExternalMarking(); 2336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The objects reachable from the roots or object groups are marked, 2338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // yet unreachable objects are unmarked. Mark objects reachable 2339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // only from weak global handles. 2340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // First we identify nonlive weak handles and mark them as pending 2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // destruction. 23438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->global_handles()->IdentifyWeakHandles( 234444f0eee88ff00398ff7f715fab053374d808c90dSteve Block &IsUnmarkedHeapObject); 2345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Then we mark the objects and process the transitive closure. 23468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor); 23473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (marking_deque_.overflowed()) { 23483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RefillMarkingDeque(); 23493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmptyMarkingDeque(); 2350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 235244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Repeat host application specific marking to mark unmarked objects 235344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // reachable from the weak roots. 235444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ProcessExternalMarking(); 2355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AfterMarking(); 23573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 23583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::AfterMarking() { 23613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Object literal map caches reference symbols (cache keys) and maps 23623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // (cache values). At this point still useful maps have already been 23633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // marked. Mark the keys for the alive values before we process the 23643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // symbol table. 23653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ProcessMapCaches(); 23663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Prune the symbol table removing all symbols only pointed to by the 2368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // symbol table. Cannot use symbol_table() here because the symbol 2369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // table is marked. 23703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SymbolTable* symbol_table = heap()->symbol_table(); 23718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch SymbolTableCleaner v(heap()); 2372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block symbol_table->IterateElements(&v); 2373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block symbol_table->ElementsRemoved(v.PointersRemoved()); 23748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->external_string_table_.Iterate(&v); 23758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->external_string_table_.CleanUp(); 2376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2377f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Process the weak references. 2378f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch MarkCompactWeakObjectRetainer mark_compact_object_retainer; 23798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->ProcessWeakReferences(&mark_compact_object_retainer); 2380f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 2381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove object groups after marking phase. 23828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->global_handles()->RemoveObjectGroups(); 23838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch heap()->isolate()->global_handles()->RemoveImplicitRefGroups(); 2384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Flush code from collected candidates. 238644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (is_code_flushing_enabled()) { 238744f0eee88ff00398ff7f715fab053374d808c90dSteve Block code_flusher_->ProcessCandidates(); 238844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 2389e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 23903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!FLAG_watch_ic_patching) { 23913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clean up dead objects from the runtime profiler. 23923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->isolate()->runtime_profiler()->RemoveDeadSamples(); 23933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid MarkCompactCollector::ProcessMapCaches() { 23983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* raw_context = heap()->global_contexts_list_; 23993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (raw_context != heap()->undefined_value()) { 24003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Context* context = reinterpret_cast<Context*>(raw_context); 24013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IsMarked(context)) { 24023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HeapObject* raw_map_cache = 24033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HeapObject::cast(context->get(Context::MAP_CACHE_INDEX)); 24043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // A map cache may be reachable from the stack. In this case 24053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // it's already transitively marked and it's too late to clean 24063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // up its parts. 24073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IsMarked(raw_map_cache) && 24083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch raw_map_cache != heap()->undefined_value()) { 24093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MapCache* map_cache = reinterpret_cast<MapCache*>(raw_map_cache); 24103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int existing_elements = map_cache->NumberOfElements(); 24113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int used_elements = 0; 24123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = MapCache::kElementsStartIndex; 24133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch i < map_cache->length(); 24143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch i += MapCache::kEntrySize) { 24153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* raw_key = map_cache->get(i); 24163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (raw_key == heap()->undefined_value() || 24173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_key == heap()->the_hole_value()) continue; 24183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch STATIC_ASSERT(MapCache::kEntrySize == 2); 24193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* raw_map = map_cache->get(i + 1); 24203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_map->IsHeapObject() && IsMarked(raw_map)) { 24213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++used_elements; 24223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 24233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Delete useless entries with unmarked maps. 24243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(raw_map->IsMap()); 24253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map_cache->set_the_hole(i); 24263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map_cache->set_the_hole(i + 1); 24273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 24283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 24293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (used_elements == 0) { 24303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->set(Context::MAP_CACHE_INDEX, heap()->undefined_value()); 24313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 24323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Note: we don't actually shrink the cache here to avoid 24333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // extra complexity during GC. We rely on subsequent cache 24343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // usages (EnsureCapacity) to do this. 24353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch map_cache->ElementsRemoved(existing_elements - used_elements); 24363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit map_cache_markbit = Marking::MarkBitFrom(map_cache); 24373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkObject(map_cache, map_cache_markbit); 24383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 24393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 24403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 24413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Move to next element in the list. 24423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch raw_context = context->get(Context::NEXT_CONTEXT_LINK); 24433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 24443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ProcessMarkingDeque(); 244585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 2446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 24483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::ReattachInitialMaps() { 24493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObjectIterator map_iterator(heap()->map_space()); 24503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* obj = map_iterator.Next(); 24513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj != NULL; 24523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj = map_iterator.Next()) { 24533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (obj->IsFreeSpace()) continue; 24543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* map = Map::cast(obj); 245585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 24563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 24573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map->instance_type() < FIRST_JS_RECEIVER_TYPE) continue; 245885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 24593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map->attached_to_shared_function_info()) { 24603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); 24613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 24623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MarkCompactCollector::ClearNonLiveTransitions() { 24673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObjectIterator map_iterator(heap()->map_space()); 2468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate over the map space, setting map transitions that go from 2469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a marked map to an unmarked map to null transitions. At the same time, 2470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // set all the prototype fields of maps back to their original value, 2471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // dropping the back pointers temporarily stored in the prototype field. 2472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Setting the prototype field requires following the linked list of 2473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // back pointers, reversing them all at once. This allows us to find 2474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // those maps with map transitions that need to be nulled, and only 2475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scan the descriptor arrays of those maps, not all maps. 2476e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // All of these actions are carried out only on maps of JSObjects 2477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and related subtypes. 24783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* obj = map_iterator.Next(); 24793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj != NULL; obj = map_iterator.Next()) { 2480d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Map* map = reinterpret_cast<Map*>(obj); 24813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit map_mark = Marking::MarkBitFrom(map); 24823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map->IsFreeSpace()) continue; 2483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(map->IsMap()); 2485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Only JSObject and subtypes have map transitions and back pointers. 24863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE); 24873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue; 24880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 24893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map_mark.Get() && 24903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map->attached_to_shared_function_info()) { 24910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // This map is used for inobject slack tracking and has been detached 24920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // from SharedFunctionInfo during the mark phase. 24930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Since it survived the GC, reattach it now. 24940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); 24950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 24960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 24973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ClearNonLivePrototypeTransitions(map); 24983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ClearNonLiveMapTransitions(map, map_mark); 24993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2501c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 25023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { 25043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int number_of_transitions = map->NumberOfProtoTransitions(); 25053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* prototype_transitions = map->prototype_transitions(); 25063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int new_number_of_transitions = 0; 25083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const int header = Map::kProtoTransitionHeaderSize; 25093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const int proto_offset = header + Map::kProtoTransitionPrototypeOffset; 25103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const int map_offset = header + Map::kProtoTransitionMapOffset; 25113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const int step = Map::kProtoTransitionElementsPerEntry; 25123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < number_of_transitions; i++) { 25133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* prototype = prototype_transitions->get(proto_offset + i * step); 25143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* cached_map = prototype_transitions->get(map_offset + i * step); 25153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IsMarked(prototype) && IsMarked(cached_map)) { 25163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int proto_index = proto_offset + new_number_of_transitions * step; 25173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int map_index = map_offset + new_number_of_transitions * step; 25183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (new_number_of_transitions != i) { 25193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch prototype_transitions->set_unchecked( 25203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_, 25213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch proto_index, 25223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch prototype, 25233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UPDATE_WRITE_BARRIER); 25243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch prototype_transitions->set_unchecked( 25253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_, 25263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map_index, 25273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cached_map, 25283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SKIP_WRITE_BARRIER); 252985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 25303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** slot = 25313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject::RawField(prototype_transitions, 25323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::OffsetOfElementAt(proto_index)); 25333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSlot(slot, slot, prototype); 25343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_number_of_transitions++; 25353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (new_number_of_transitions != number_of_transitions) { 25393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map->SetNumberOfProtoTransitions(new_number_of_transitions); 25403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Fill slots that became free with undefined value. 25433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = new_number_of_transitions * step; 25443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i < number_of_transitions * step; 25453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i++) { 25463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch prototype_transitions->set_undefined(heap_, header + i); 25473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 25493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::ClearNonLiveMapTransitions(Map* map, 25523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit map_mark) { 25533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Follow the chain of back pointers to find the prototype. 25543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* real_prototype = map; 25553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (real_prototype->IsMap()) { 25563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch real_prototype = Map::cast(real_prototype)->prototype(); 25573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(real_prototype->IsHeapObject()); 25583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Follow back pointers, setting them to prototype, clearing map transitions 25613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // when necessary. 25623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* current = map; 25633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool current_is_alive = map_mark.Get(); 25643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool on_dead_path = !current_is_alive; 25653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (current->IsMap()) { 25663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* next = current->prototype(); 25673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // There should never be a dead map above a live map. 25683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(on_dead_path || current_is_alive); 25693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // A live map above a dead map indicates a dead transition. This test will 25713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // always be false on the first iteration. 25723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (on_dead_path && current_is_alive) { 25733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch on_dead_path = false; 25743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current->ClearNonLiveTransitions(heap(), real_prototype); 2575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 25763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** slot = HeapObject::RawField(current, Map::kPrototypeOffset); 25783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *slot = real_prototype; 25793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (current_is_alive) RecordSlot(slot, slot, real_prototype); 25803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current = reinterpret_cast<Map*>(next); 25823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current_is_alive = Marking::MarkBitFrom(current).Get(); 2583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 258769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid MarkCompactCollector::ProcessWeakMaps() { 258869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* weak_map_obj = encountered_weak_maps(); 258969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch while (weak_map_obj != Smi::FromInt(0)) { 25903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj))); 259169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj); 25923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectHashTable* table = ObjectHashTable::cast(weak_map->table()); 259369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < table->Capacity(); i++) { 25943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { 259569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* value = table->get(table->EntryToValueIndex(i)); 25963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticMarkingVisitor::VisitPointer(heap(), &value); 259769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch table->set_unchecked(heap(), 259869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch table->EntryToValueIndex(i), 259969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch value, 260069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch UPDATE_WRITE_BARRIER); 260169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 260269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 260369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch weak_map_obj = weak_map->next(); 260469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 260569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 260669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 260769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 260869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid MarkCompactCollector::ClearWeakMaps() { 260969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* weak_map_obj = encountered_weak_maps(); 261069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch while (weak_map_obj != Smi::FromInt(0)) { 26113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj))); 261269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj); 26133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectHashTable* table = ObjectHashTable::cast(weak_map->table()); 261469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < table->Capacity(); i++) { 26153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { 26163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch table->RemoveEntry(i); 261769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 261869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 261969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch weak_map_obj = weak_map->next(); 262069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch weak_map->set_next(Smi::FromInt(0)); 262169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 262269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch set_encountered_weak_maps(Smi::FromInt(0)); 262369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 262469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 26253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// We scavange new space simultaneously with sweeping. This is done in two 26273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// passes. 2628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 26293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The first pass migrates all alive objects from one semispace to another or 26303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// promotes them to old space. Forwarding address is written directly into 26313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// first word of object without any encoding. If object is dead we write 26323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// NULL as a forwarding address. 263385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// 26343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The second pass updates pointers to new space in all spaces. It is possible 26353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// to encounter pointers to dead new space objects during traversal of pointers 26363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// to new space. We should clear them to avoid encountering them during next 26373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// pointer iteration. This is an issue if the store buffer overflows and we 26383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// have to scan the entire old space, including dead objects, looking for 26393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// pointers to new space. 26403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::MigrateObject(Address dst, 26413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address src, 26423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int size, 26433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllocationSpace dest) { 26443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP_PROFILE(heap(), ObjectMoveEvent(src, dst)); 26453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (dest == OLD_POINTER_SPACE || dest == LO_SPACE) { 26463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address src_slot = src; 26473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address dst_slot = dst; 26483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IsAligned(size, kPointerSize)); 26493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int remaining = size / kPointerSize; remaining > 0; remaining--) { 26513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* value = Memory::Object_at(src_slot); 26523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Memory::Object_at(dst_slot) = value; 26543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (heap_->InNewSpace(value)) { 26563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->store_buffer()->Mark(dst_slot); 26573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { 26583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::AddTo(&slots_buffer_allocator_, 26593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &migration_slots_buffer_, 26603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Object**>(dst_slot), 26613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::IGNORE_OVERFLOW); 26623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch src_slot += kPointerSize; 26653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch dst_slot += kPointerSize; 2666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (compacting_ && HeapObject::FromAddress(dst)->IsJSFunction()) { 26693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address code_entry_slot = dst + JSFunction::kCodeEntryOffset; 26703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address code_entry = Memory::Address_at(code_entry_slot); 2671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 26723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { 26733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::AddTo(&slots_buffer_allocator_, 26743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &migration_slots_buffer_, 26753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::CODE_ENTRY_SLOT, 26763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code_entry_slot, 26773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::IGNORE_OVERFLOW); 2678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 26803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (dest == CODE_SPACE) { 26813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(heap()->isolate(), CodeMoveEvent(src, dst)); 26823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->MoveBlock(dst, src, size); 26833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::AddTo(&slots_buffer_allocator_, 26843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &migration_slots_buffer_, 26853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::RELOCATED_CODE_OBJECT, 26863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch dst, 26873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::IGNORE_OVERFLOW); 26883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::cast(HeapObject::FromAddress(dst))->Relocate(dst - src); 26897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 26903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(dest == OLD_DATA_SPACE || dest == NEW_SPACE); 26913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->MoveBlock(dst, src, size); 26927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 26936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Memory::Address_at(src) = dst; 26946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 26956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 26966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 26976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Visitor for updating pointers from live objects in old spaces to new space. 26986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// It does not expect to encounter pointers to dead objects. 26993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass PointersUpdatingVisitor: public ObjectVisitor { 27006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: 27013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) { } 270244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 27036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void VisitPointer(Object** p) { 27043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UpdatePointer(p); 27056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 27066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void VisitPointers(Object** start, Object** end) { 27083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (Object** p = start; p < end; p++) UpdatePointer(p); 27093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void VisitEmbeddedPointer(RelocInfo* rinfo) { 27123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); 27133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* target = rinfo->target_object(); 27143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitPointer(&target); 27153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch rinfo->set_target_object(target); 27166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 27176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void VisitCodeTarget(RelocInfo* rinfo) { 27196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); 27206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); 27216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block VisitPointer(&target); 27226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block rinfo->set_target_address(Code::cast(target)->instruction_start()); 27236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 27246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block void VisitDebugTarget(RelocInfo* rinfo) { 27267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && 27277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch rinfo->IsPatchedReturnSequence()) || 27287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 27297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch rinfo->IsPatchedDebugBreakSlotSequence())); 27306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); 27316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block VisitPointer(&target); 27326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block rinfo->set_call_address(Code::cast(target)->instruction_start()); 27336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 27343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 27353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline void UpdateSlot(Heap* heap, Object** slot) { 27363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* obj = *slot; 27373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!obj->IsHeapObject()) return; 27393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* heap_obj = HeapObject::cast(obj); 27413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MapWord map_word = heap_obj->map_word(); 27433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map_word.IsForwardingAddress()) { 27443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(heap->InFromSpace(heap_obj) || 27453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkCompactCollector::IsOnEvacuationCandidate(heap_obj)); 27463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* target = map_word.ToForwardingAddress(); 27473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *slot = target; 27483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!heap->InFromSpace(target) && 27493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !MarkCompactCollector::IsOnEvacuationCandidate(target)); 27503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 275344f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 27543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline void UpdatePointer(Object** p) { 27553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UpdateSlot(heap_, p); 27563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 275844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Heap* heap_; 27596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 27606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 27623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void UpdatePointer(HeapObject** p, HeapObject* object) { 27633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(*p == object); 27646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address old_addr = object->address(); 27666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Address new_addr = Memory::Address_at(old_addr); 27686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The new space sweep will overwrite the map word of dead objects 27703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // with NULL. In this case we do not need to transfer this entry to 27713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the store buffer which we are rebuilding. 27723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (new_addr != NULL) { 277385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch *p = HeapObject::FromAddress(new_addr); 27743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 27753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We have to zap this pointer, because the store buffer may overflow later, 27763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // and then we have to scan the entire heap and we don't want to find 27773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // spurious newspace pointers in the old space. 27783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *p = reinterpret_cast<HeapObject*>(Smi::FromInt(0)); 27797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 27806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 27816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic String* UpdateReferenceInExternalStringTableEntry(Heap* heap, 27843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object** p) { 27853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MapWord map_word = HeapObject::cast(*p)->map_word(); 2786592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 27873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map_word.IsForwardingAddress()) { 27883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return String::cast(map_word.ToForwardingAddress()); 27893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2790592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 27913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return String::cast(*p); 27923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool MarkCompactCollector::TryPromoteObject(HeapObject* object, 27963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int object_size) { 27976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Object* result; 27986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 27993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (object_size > Page::kMaxNonCodeHeapObjectSize) { 28005913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* maybe_result = 28013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->lo_space()->AllocateRaw(object_size, NOT_EXECUTABLE); 28025913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (maybe_result->ToObject(&result)) { 28036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HeapObject* target = HeapObject::cast(result); 28043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MigrateObject(target->address(), 28053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object->address(), 28063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object_size, 28073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LO_SPACE); 28083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->mark_compact_collector()->tracer()-> 2809f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke increment_promoted_objects_size(object_size); 28106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 28116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 28126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 28133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch OldSpace* target_space = heap()->TargetSpace(object); 28146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(target_space == heap()->old_pointer_space() || 28163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target_space == heap()->old_data_space()); 28175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* maybe_result = target_space->AllocateRaw(object_size); 28185913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (maybe_result->ToObject(&result)) { 28196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block HeapObject* target = HeapObject::cast(result); 28203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MigrateObject(target->address(), 28217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch object->address(), 28227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch object_size, 28233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target_space->identity()); 28243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->mark_compact_collector()->tracer()-> 2825f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke increment_promoted_objects_size(object_size); 28266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 28276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 28286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 28296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 28316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 28326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::EvacuateNewSpace() { 28353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // There are soft limits in the allocation code, designed trigger a mark 28363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // sweep collection by failing allocations. But since we are already in 28373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a mark-sweep allocation, there is no sense in trying to trigger one. 28383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AlwaysAllocateScope scope; 28393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->CheckNewSpaceExpansionCriteria(); 28403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NewSpace* new_space = heap()->new_space(); 28426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Store allocation range before flipping semispaces. 28443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address from_bottom = new_space->bottom(); 28453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address from_top = new_space->top(); 28466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Flip the semispaces. After flipping, to space is empty, from space has 28486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // live objects. 28493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->Flip(); 28503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->ResetAllocationInfo(); 28516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int survivors_size = 0; 28536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // First pass: traverse all objects in inactive semispace, remove marks, 28553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // migrate live objects and write forwarding addresses. This stage puts 28563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // new entries in the store buffer and may cause some pages to be marked 28573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // scan-on-scavenge. 28583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SemiSpaceIterator from_it(from_bottom, from_top); 28593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* object = from_it.Next(); 28603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object != NULL; 28613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object = from_it.Next()) { 28623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark_bit = Marking::MarkBitFrom(object); 28633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mark_bit.Get()) { 28643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mark_bit.Clear(); 28653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Don't bother decrementing live bytes count. We'll discard the 28663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // entire page at the end. 28673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int size = object->Size(); 28686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block survivors_size += size; 28696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Aggressively promote young survivors to the old space. 28713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (TryPromoteObject(object, size)) { 28726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block continue; 28736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 28746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Promotion failed. Just migrate object to another semispace. 28763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* allocation = new_space->AllocateRaw(size); 28773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (allocation->IsFailure()) { 28783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!new_space->AddFreshPage()) { 28793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Shouldn't happen. We are sweeping linearly, and to-space 28803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // has the same number of pages as from-space, so there is 28813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // always room. 28823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 28833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 28843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch allocation = new_space->AllocateRaw(size); 28853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!allocation->IsFailure()); 28863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 28873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* target = allocation->ToObjectUnchecked(); 28886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MigrateObject(HeapObject::cast(target)->address(), 28903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object->address(), 28917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch size, 28923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NEW_SPACE); 28936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 28941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Process the dead object before we write a NULL into its header. 28951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block LiveObjectList::ProcessNonLive(object); 28961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 28973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Mark dead objects in the new space with null in their map field. 28983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Memory::Address_at(object->address()) = NULL; 28996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 29006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 29016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 29023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->IncrementYoungSurvivorsCounter(survivors_size); 29033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_space->set_age_mark(new_space->top()); 29043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 29056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 29066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 29073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) { 29083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AlwaysAllocateScope always_allocate; 29093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 29103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(p->IsEvacuationCandidate() && !p->WasSwept()); 29113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit::CellType* cells = p->markbits()->cells(); 29123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->MarkSweptPrecisely(); 29133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int last_cell_index = 29153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 29163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 29173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(p->area_end()))); 29183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address cell_base = p->area_start(); 29203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int cell_index = Bitmap::IndexToCell( 29213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 29223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(cell_base))); 29233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offsets[16]; 29253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (; 29273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index < last_cell_index; 29283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index++, cell_base += 32 * kPointerSize) { 29293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((unsigned)cell_index == 29303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 29313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 29323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(cell_base)))); 29333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (cells[cell_index] == 0) continue; 29343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); 29363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < live_objects; i++) { 29373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address object_addr = cell_base + offsets[i] * kPointerSize; 29383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* object = HeapObject::FromAddress(object_addr); 29393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); 29403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int size = object->Size(); 29423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* target = space->AllocateRaw(size); 29443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (target->IsFailure()) { 29453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // OS refused to give us memory. 29463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V8::FatalProcessOutOfMemory("Evacuation"); 29473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 29483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 29496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 29503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* target_object = target->ToObjectUnchecked(); 29516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 29523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MigrateObject(HeapObject::cast(target_object)->address(), 29533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object_addr, 29543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch size, 29553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->identity()); 29563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(object->map_word().IsForwardingAddress()); 295785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 295885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 29593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clear marking bits for current cell. 29603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cells[cell_index] = 0; 29613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 29623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ResetLiveBytes(); 2963592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 29646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::EvacuatePages() { 29673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int npages = evacuation_candidates_.length(); 29683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < npages; i++) { 29693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = evacuation_candidates_[i]; 29703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(p->IsEvacuationCandidate() || 29713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 29723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (p->IsEvacuationCandidate()) { 29733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // During compaction we might have to request a new page. 29743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that space still have room for that. 29753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (static_cast<PagedSpace*>(p->owner())->CanExpand()) { 29763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EvacuateLiveObjectsFromPage(p); 2977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 29783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Without room for expansion evacuation is not guaranteed to succeed. 29793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pessimistically abandon unevacuated pages. 29803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int j = i; j < npages; j++) { 29813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* page = evacuation_candidates_[j]; 29823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address()); 29833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch page->ClearEvacuationCandidate(); 29843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch page->SetFlag(Page::RESCAN_ON_EVACUATION); 2985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 29863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 2987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 29893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 29903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 29933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass EvacuationWeakObjectRetainer : public WeakObjectRetainer { 29943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 29953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Object* RetainAs(Object* object) { 29963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (object->IsHeapObject()) { 29973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* heap_object = HeapObject::cast(object); 29983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MapWord map_word = heap_object->map_word(); 29993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map_word.IsForwardingAddress()) { 30003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return map_word.ToForwardingAddress(); 30016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 3002592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 30033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return object; 300485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 30053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 300685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 300785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 30083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic inline void UpdateSlot(ObjectVisitor* v, 30093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::SlotType slot_type, 30103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address addr) { 30113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (slot_type) { 30123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case SlotsBuffer::CODE_TARGET_SLOT: { 30133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo rinfo(addr, RelocInfo::CODE_TARGET, 0, NULL); 30143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch rinfo.Visit(v); 30153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 3016592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 30173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case SlotsBuffer::CODE_ENTRY_SLOT: { 30183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v->VisitCodeEntry(addr); 30193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 30203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case SlotsBuffer::RELOCATED_CODE_OBJECT: { 30223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* obj = HeapObject::FromAddress(addr); 30233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::cast(obj)->CodeIterateBody(v); 30243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 30253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case SlotsBuffer::DEBUG_TARGET_SLOT: { 30273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo rinfo(addr, RelocInfo::DEBUG_BREAK_SLOT, 0, NULL); 30283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (rinfo.IsPatchedDebugBreakSlotSequence()) rinfo.Visit(v); 30293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 30303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case SlotsBuffer::JS_RETURN_SLOT: { 30323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo rinfo(addr, RelocInfo::JS_RETURN, 0, NULL); 30333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(v); 30343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 30353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case SlotsBuffer::EMBEDDED_OBJECT_SLOT: { 30373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo rinfo(addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL); 30383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch rinfo.Visit(v); 30393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 30403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 30423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 30433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 30446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 3045592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 30466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 30476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 30483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum SweepingMode { 30493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SWEEP_ONLY, 30503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SWEEP_AND_VISIT_LIVE_OBJECTS 30513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 305285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 305385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 30543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum SkipListRebuildingMode { 30553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch REBUILD_SKIP_LIST, 30563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IGNORE_SKIP_LIST 3057592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}; 30586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 30596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 30603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Sweep a space precisely. After this has been done the space can 30613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// be iterated precisely, hitting only the live objects. Code space 30623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// is always swept precisely because we want to be able to iterate 30633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// over it. Map space is swept precisely, because it is not compacted. 30643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Slots in live objects pointing into evacuation candidates are updated 30653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// if requested. 30663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate<SweepingMode sweeping_mode, SkipListRebuildingMode skip_list_mode> 30673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void SweepPrecisely(PagedSpace* space, 30683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p, 30693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectVisitor* v) { 30703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 30713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(skip_list_mode == REBUILD_SKIP_LIST, 30723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->identity() == CODE_SPACE); 30733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); 30743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit::CellType* cells = p->markbits()->cells(); 30763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->MarkSweptPrecisely(); 30773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int last_cell_index = 30793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 30803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 30813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(p->area_end()))); 30823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address free_start = p->area_start(); 30843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int cell_index = 30853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 30863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 30873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(free_start))); 30883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 30903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address object_address = free_start; 30913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offsets[16]; 30923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SkipList* skip_list = p->skip_list(); 30943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int curr_region = -1; 30953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { 30963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch skip_list->Clear(); 30973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (; 31003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index < last_cell_index; 31013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index++, object_address += 32 * kPointerSize) { 31023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((unsigned)cell_index == 31033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 31043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 31053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(object_address)))); 31063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); 31073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int live_index = 0; 31083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for ( ; live_objects != 0; live_objects--) { 31093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address free_end = object_address + offsets[live_index++] * kPointerSize; 31103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (free_end != free_start) { 31113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->Free(free_start, static_cast<int>(free_end - free_start)); 31123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* live_object = HeapObject::FromAddress(free_end); 31143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); 31153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* map = live_object->map(); 31163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int size = live_object->SizeFromMap(map); 31173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { 31183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch live_object->IterateBody(map->instance_type(), size, v); 31193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { 31213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int new_region_start = 31223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SkipList::RegionNumber(free_end); 31233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int new_region_end = 31243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SkipList::RegionNumber(free_end + size - kPointerSize); 31253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (new_region_start != curr_region || 31263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_region_end != curr_region) { 31273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch skip_list->AddObject(free_end, size); 31283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch curr_region = new_region_end; 31293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch free_start = free_end + size; 3132592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 31333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clear marking bits for current cell. 31343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cells[cell_index] = 0; 3135592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 31363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (free_start != p->area_end()) { 31373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->Free(free_start, static_cast<int>(p->area_end() - free_start)); 313885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 31393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ResetLiveBytes(); 31403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3142592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 31433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) { 31443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = Page::FromAddress(code->address()); 3145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (p->IsEvacuationCandidate() || 31473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 31483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return false; 314985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 3150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address code_start = code->address(); 31523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address code_end = code_start + code->Size(); 3153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t start_index = MemoryChunk::FastAddressToMarkbitIndex(code_start); 31553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t end_index = 31563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk::FastAddressToMarkbitIndex(code_end - kPointerSize); 3157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap* b = p->markbits(); 3159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit start_mark_bit = b->MarkBitFromIndex(start_index); 31613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit end_mark_bit = b->MarkBitFromIndex(end_index); 316285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 31633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit::CellType* start_cell = start_mark_bit.cell(); 31643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit::CellType* end_cell = end_mark_bit.cell(); 316585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 31663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (value) { 31673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit::CellType start_mask = ~(start_mark_bit.mask() - 1); 31683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit::CellType end_mask = (end_mark_bit.mask() << 1) - 1; 316985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 31703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (start_cell == end_cell) { 31713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *start_cell |= start_mask & end_mask; 31723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 31733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *start_cell |= start_mask; 31743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (MarkBit::CellType* cell = start_cell + 1; cell < end_cell; cell++) { 31753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *cell = ~0; 31763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *end_cell |= end_mask; 3178592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 31793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 31803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (MarkBit::CellType* cell = start_cell ; cell <= end_cell; cell++) { 31813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *cell = 0; 318285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 318385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 3184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return true; 31863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3187e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3188e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 31893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool IsOnInvalidatedCodeObject(Address addr) { 31903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We did not record any slots in large objects thus 31913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // we can safely go to the page from the slot address. 31923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = Page::FromAddress(addr); 3193e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 31943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // First check owner's identity because old pointer and old data spaces 31953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // are swept lazily and might still have non-zero mark-bits on some 31963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // pages. 31973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (p->owner()->identity() != CODE_SPACE) return false; 3198e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 31993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // In code space only bits on evacuation candidates (but we don't record 32003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // any slots on them) and under invalidated code objects are non-zero. 32013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark_bit = 32023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); 3203e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 32043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return mark_bit.Get(); 32053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3206e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3207e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 32083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::InvalidateCode(Code* code) { 32093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (heap_->incremental_marking()->IsCompacting() && 32103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !ShouldSkipEvacuationSlotRecording(code)) { 32113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(compacting_); 3212e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 32133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the object is white than no slots were recorded on it yet. 32143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit mark_bit = Marking::MarkBitFrom(code); 32153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Marking::IsWhite(mark_bit)) return; 3216e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 32173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch invalidated_code_.Add(code); 3218e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 32193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3220e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 322185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 32223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool MarkCompactCollector::MarkInvalidatedCode() { 32233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool code_marked = false; 322485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 32253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = invalidated_code_.length(); 32263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < length; i++) { 32273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = invalidated_code_[i]; 322885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 32293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (SetMarkBitsUnderInvalidatedCode(code, true)) { 32303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code_marked = true; 32313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 323285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 32338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 32343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code_marked; 32353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3236e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 323785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 32383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::RemoveDeadInvalidatedCode() { 32393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = invalidated_code_.length(); 32403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < length; i++) { 32413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IsMarked(invalidated_code_[i])) invalidated_code_[i] = NULL; 3242592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 3243592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 324444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3245e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 32463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::ProcessInvalidatedCode(ObjectVisitor* visitor) { 32473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = invalidated_code_.length(); 32483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < length; i++) { 32493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = invalidated_code_[i]; 32503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (code != NULL) { 32513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->Iterate(visitor); 32523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetMarkBitsUnderInvalidatedCode(code, false); 3253e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3254592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 32553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch invalidated_code_.Rewind(0); 3256592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 3257e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3258e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 32593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::EvacuateNewSpaceAndCandidates() { 32603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool code_slots_filtering_required; 32613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); 32623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code_slots_filtering_required = MarkInvalidatedCode(); 3263e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 32643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EvacuateNewSpace(); 3265e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3266e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3267e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 32683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_EVACUATE_PAGES); 32693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EvacuatePages(); 3270e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3271e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 32723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Second pass: find pointers to new space and update them. 32733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PointersUpdatingVisitor updating_visitor(heap()); 32743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { GCTracer::Scope gc_scope(tracer_, 32763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GCTracer::Scope::MC_UPDATE_NEW_TO_NEW_POINTERS); 32773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update pointers in to space. 32783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SemiSpaceIterator to_it(heap()->new_space()->bottom(), 32793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->new_space()->top()); 32803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* object = to_it.Next(); 32813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object != NULL; 32823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object = to_it.Next()) { 32833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* map = object->map(); 32843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object->IterateBody(map->instance_type(), 32853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object->SizeFromMap(map), 32863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &updating_visitor); 32873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3288592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 3289592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 32903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { GCTracer::Scope gc_scope(tracer_, 32913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GCTracer::Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS); 32923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update roots. 32933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); 32943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList::IterateElements(&updating_visitor); 3295592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 3296592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 32973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { GCTracer::Scope gc_scope(tracer_, 32983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GCTracer::Scope::MC_UPDATE_OLD_TO_NEW_POINTERS); 32993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StoreBufferRebuildScope scope(heap_, 33003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->store_buffer(), 33013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &Heap::ScavengeStoreBufferCallback); 33023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer); 3303592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 3304592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 33053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { GCTracer::Scope gc_scope(tracer_, 33063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GCTracer::Scope::MC_UPDATE_POINTERS_TO_EVACUATED); 33073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::UpdateSlotsRecordedIn(heap_, 33083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch migration_slots_buffer_, 33093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code_slots_filtering_required); 33103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_fragmentation) { 33113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(" migration slots buffer: %d\n", 33123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::SizeOfChain(migration_slots_buffer_)); 33133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3314e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 33153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (compacting_ && was_marked_incrementally_) { 33163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // It's difficult to filter out slots recorded for large objects. 33173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LargeObjectIterator it(heap_->lo_space()); 33183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 33193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // LargeObjectSpace is not swept yet thus we have to skip 33203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // dead objects explicitly. 33213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IsMarked(obj)) continue; 33223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = Page::FromAddress(obj->address()); 33243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 33253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj->Iterate(&updating_visitor); 33263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ClearFlag(Page::RESCAN_ON_EVACUATION); 33273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 332885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 3329592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 33303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 33317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int npages = evacuation_candidates_.length(); 33333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { GCTracer::Scope gc_scope( 33343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch tracer_, GCTracer::Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED); 33353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < npages; i++) { 33363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = evacuation_candidates_[i]; 33373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(p->IsEvacuationCandidate() || 33383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 33393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (p->IsEvacuationCandidate()) { 33413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::UpdateSlotsRecordedIn(heap_, 33423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->slots_buffer(), 33433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code_slots_filtering_required); 33443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_fragmentation) { 33453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(" page %p slots buffer: %d\n", 33463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<void*>(p), 33473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::SizeOfChain(p->slots_buffer())); 33483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 33497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Important: skip list should be cleared only after roots were updated 33513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // because root iteration traverses the stack and might have to find 33523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // code objects from non-updated pc pointing into evacuation candidate. 33533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SkipList* list = p->skip_list(); 33543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (list != NULL) list->Clear(); 33553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 33563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_gc_verbose) { 33573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 33583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<intptr_t>(p)); 33593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 33603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 33613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 33623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (space->identity()) { 33643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case OLD_DATA_SPACE: 33653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepConservatively(space, p); 33663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 33673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case OLD_POINTER_SPACE: 33683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, IGNORE_SKIP_LIST>( 33693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space, p, &updating_visitor); 33703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 33713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CODE_SPACE: 33723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, REBUILD_SKIP_LIST>( 33733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space, p, &updating_visitor); 33743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 33753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 33763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 33773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 33783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 33793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 338085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 33815d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3382e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 33833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_UPDATE_MISC_POINTERS); 3384e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 33853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update pointers from cells. 33863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObjectIterator cell_iterator(heap_->cell_space()); 33873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (HeapObject* cell = cell_iterator.Next(); 33883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell != NULL; 33893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell = cell_iterator.Next()) { 33903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (cell->IsJSGlobalPropertyCell()) { 33913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address value_address = 33923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Address>(cell) + 33933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); 33943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); 33953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3396592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 3397e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 33983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update pointer from the global contexts list. 33993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch updating_visitor.VisitPointer(heap_->global_contexts_list_address()); 3400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->symbol_table()->Iterate(&updating_visitor); 3402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update pointers from external string table. 34043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->UpdateReferencesInExternalStringTable( 34053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &UpdateReferenceInExternalStringTableEntry); 3406592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 34073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!FLAG_watch_ic_patching) { 34083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update JSFunction pointers from the runtime profiler. 34093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->isolate()->runtime_profiler()->UpdateSamplesAfterCompact( 34103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &updating_visitor); 34113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EvacuationWeakObjectRetainer evacuation_object_retainer; 34143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->ProcessWeakReferences(&evacuation_object_retainer); 3415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Visit invalidated code (we ignored all slots on it) and clear mark-bits 34173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // under it. 34183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ProcessInvalidatedCode(&updating_visitor); 3419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 342085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch#ifdef DEBUG 34213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_verify_heap) { 34223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VerifyEvacuation(heap_); 342385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 342485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch#endif 3425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); 34273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(migration_slots_buffer_ == NULL); 34283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < npages; i++) { 34293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = evacuation_candidates_[i]; 34303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!p->IsEvacuationCandidate()) continue; 34313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 34323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->Free(p->area_start(), p->area_size()); 34333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->set_scan_on_scavenge(false); 34343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); 34353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ResetLiveBytes(); 34363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->ReleasePage(p); 34373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 34383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch evacuation_candidates_.Rewind(0); 34393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compacting_ = false; 3440592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 3441592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3442592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 34433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const int kStartTableEntriesPerLine = 5; 34443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const int kStartTableLines = 171; 34453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const int kStartTableInvalidLine = 127; 34463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const int kStartTableUnusedEntry = 126; 3447592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 34483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define _ kStartTableUnusedEntry 34493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define X kStartTableInvalidLine 34503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Mark-bit to object start offset table. 34513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 34523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The line is indexed by the mark bits in a byte. The first number on 34533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// the line describes the number of live object starts for the line and the 34543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// other numbers on the line describe the offsets (in words) of the object 34553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// starts. 34563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 34573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Since objects are at least 2 words large we don't have entries for two 34583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// consecutive 1 bits. All entries after 170 have at least 2 consecutive bits. 34593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochchar kStartTable[kStartTableLines * kStartTableEntriesPerLine] = { 34603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 0, _, _, _, _, // 0 34613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1, 0, _, _, _, // 1 34623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1, 1, _, _, _, // 2 34633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 3 34643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1, 2, _, _, _, // 4 34653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 0, 2, _, _, // 5 34663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 6 34673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 7 34683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1, 3, _, _, _, // 8 34693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 0, 3, _, _, // 9 34703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 1, 3, _, _, // 10 34713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 11 34723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 12 34733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 13 34743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 14 34753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 15 34763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1, 4, _, _, _, // 16 34773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 0, 4, _, _, // 17 34783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 1, 4, _, _, // 18 34793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 19 34803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 2, 4, _, _, // 20 34813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 2, 4, _, // 21 34823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 22 34833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 23 34843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 24 34853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 25 34863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 26 34873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 27 34883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 28 34893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 29 34903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 30 34913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 31 34923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1, 5, _, _, _, // 32 34933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 0, 5, _, _, // 33 34943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 1, 5, _, _, // 34 34953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 35 34963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 2, 5, _, _, // 36 34973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 2, 5, _, // 37 34983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 38 34993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 39 35003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 3, 5, _, _, // 40 35013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 3, 5, _, // 41 35023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 1, 3, 5, _, // 42 35033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 43 35043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 44 35053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 45 35063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 46 35073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 47 35083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 48 35093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 49 35103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 50 35113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 51 35123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 52 35133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 53 35143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 54 35153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 55 35163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 56 35173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 57 35183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 58 35193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 59 35203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 60 35213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 61 35223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 62 35233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 63 35243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1, 6, _, _, _, // 64 35253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 0, 6, _, _, // 65 35263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 1, 6, _, _, // 66 35273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 67 35283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 2, 6, _, _, // 68 35293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 2, 6, _, // 69 35303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 70 35313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 71 35323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 3, 6, _, _, // 72 35333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 3, 6, _, // 73 35343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 1, 3, 6, _, // 74 35353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 75 35363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 76 35373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 77 35383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 78 35393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 79 35403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 4, 6, _, _, // 80 35413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 4, 6, _, // 81 35423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 1, 4, 6, _, // 82 35433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 83 35443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 2, 4, 6, _, // 84 35453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4, 0, 2, 4, 6, // 85 35463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 86 35473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 87 35483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 88 35493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 89 35503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 90 35513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 91 35523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 92 35533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 93 35543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 94 35553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 95 35563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 96 35573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 97 35583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 98 35593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 99 35603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 100 35613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 101 35623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 102 35633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 103 35643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 104 35653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 105 35663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 106 35673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 107 35683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 108 35693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 109 35703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 110 35713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 111 35723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 112 35733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 113 35743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 114 35753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 115 35763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 116 35773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 117 35783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 118 35793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 119 35803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 120 35813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 121 35823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 122 35833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 123 35843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 124 35853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 125 35863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 126 35873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 127 35883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1, 7, _, _, _, // 128 35893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 0, 7, _, _, // 129 35903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 1, 7, _, _, // 130 35913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 131 35923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 2, 7, _, _, // 132 35933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 2, 7, _, // 133 35943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 134 35953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 135 35963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 3, 7, _, _, // 136 35973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 3, 7, _, // 137 35983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 1, 3, 7, _, // 138 35993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 139 36003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 140 36013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 141 36023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 142 36033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 143 36043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 4, 7, _, _, // 144 36053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 4, 7, _, // 145 36063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 1, 4, 7, _, // 146 36073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 147 36083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 2, 4, 7, _, // 148 36093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4, 0, 2, 4, 7, // 149 36103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 150 36113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 151 36123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 152 36133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 153 36143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 154 36153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 155 36163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 156 36173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 157 36183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 158 36193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 159 36203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2, 5, 7, _, _, // 160 36213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 0, 5, 7, _, // 161 36223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 1, 5, 7, _, // 162 36233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 163 36243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 2, 5, 7, _, // 164 36253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4, 0, 2, 5, 7, // 165 36263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 166 36273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch X, _, _, _, _, // 167 36283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3, 3, 5, 7, _, // 168 36293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4, 0, 3, 5, 7, // 169 36303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4, 1, 3, 5, 7 // 170 36313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 36323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef _ 36333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef X 36343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Takes a word of mark bits. Returns the number of objects that start in the 36373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// range. Puts the offsets of the words in the supplied array. 36383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts) { 36393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int objects = 0; 36403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset = 0; 36413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // No consecutive 1 bits. 36433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((mark_bits & 0x180) != 0x180); 36443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((mark_bits & 0x18000) != 0x18000); 36453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((mark_bits & 0x1800000) != 0x1800000); 36463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (mark_bits != 0) { 36483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int byte = (mark_bits & 0xff); 36493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mark_bits >>= 8; 36503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (byte != 0) { 36513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(byte < kStartTableLines); // No consecutive 1 bits. 36523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch char* table = kStartTable + byte * kStartTableEntriesPerLine; 36533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int objects_in_these_8_words = table[0]; 36543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(objects_in_these_8_words != kStartTableInvalidLine); 36553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(objects_in_these_8_words < kStartTableEntriesPerLine); 36563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < objects_in_these_8_words; i++) { 36573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch starts[objects++] = offset + table[1 + i]; 36583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 36593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 36603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch offset += 8; 36613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 36623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return objects; 36633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3664592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3665592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 36663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic inline Address DigestFreeStart(Address approximate_free_start, 36673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t free_start_cell) { 36683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(free_start_cell != 0); 3669592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 36703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // No consecutive 1 bits. 36713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((free_start_cell & (free_start_cell << 1)) == 0); 3672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offsets[16]; 36743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t cell = free_start_cell; 36753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset_of_last_live; 36763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((cell & 0x80000000u) != 0) { 36773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This case would overflow below. 36783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch offset_of_last_live = 31; 36793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 36803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Remove all but one bit, the most significant. This is an optimization 36813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // that may or may not be worthwhile. 36823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell |= cell >> 16; 36833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell |= cell >> 8; 36843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell |= cell >> 4; 36853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell |= cell >> 2; 36863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell |= cell >> 1; 36873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell = (cell + 1) >> 1; 36883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int live_objects = MarkWordToObjectStarts(cell, offsets); 36893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(live_objects == 1); 36903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch offset_of_last_live = offsets[live_objects - 1]; 36913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 36923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address last_live_start = 36933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch approximate_free_start + offset_of_last_live * kPointerSize; 36943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* last_live = HeapObject::FromAddress(last_live_start); 36953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address free_start = last_live_start + last_live->Size(); 36963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return free_start; 36973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic inline Address StartOfLiveObject(Address block_address, uint32_t cell) { 37013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(cell != 0); 370244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 37033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // No consecutive 1 bits. 37043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((cell & (cell << 1)) == 0); 3705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offsets[16]; 37073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (cell == 0x80000000u) { // Avoid overflow below. 37083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return block_address + 31 * kPointerSize; 37093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 37103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t first_set_bit = ((cell ^ (cell - 1)) + 1) >> 1; 37113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((first_set_bit & cell) == first_set_bit); 37123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int live_objects = MarkWordToObjectStarts(first_set_bit, offsets); 37133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(live_objects == 1); 37143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch USE(live_objects); 37153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return block_address + offsets[0] * kPointerSize; 371685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 3717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Sweeps a space conservatively. After this has been done the larger free 37203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// spaces have been put on the free list and the smaller ones have been 37213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ignored and left untouched. A free space is always either ignored or put 37223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// on the free list, never split up into two parts. This is important 37233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// because it means that any FreeSpace maps left actually describe a region of 37243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// memory that can be ignored when scanning. Dead objects other than free 37253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// spaces will not contain the free space map. 37263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochintptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { 37273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 37283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkBit::CellType* cells = p->markbits()->cells(); 37293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->MarkSweptConservatively(); 37303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int last_cell_index = 37323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 37333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 37343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(p->area_end()))); 37353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int cell_index = 37373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 37383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 37393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(p->area_start()))); 37403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t freed_bytes = 0; 37423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This is the start of the 32 word block that we are currently looking at. 37443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address block_address = p->area_start(); 37453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip over all the dead objects at the start of the page and mark them free. 37473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (; 37483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index < last_cell_index; 37493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index++, block_address += 32 * kPointerSize) { 37503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (cells[cell_index] != 0) break; 37513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 37523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch size_t size = block_address - p->area_start(); 37533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (cell_index == last_cell_index) { 37543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch freed_bytes += static_cast<int>(space->Free(p->area_start(), 37553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(size))); 37563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(0, p->LiveBytes()); 37573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return freed_bytes; 37583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 37593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Grow the size of the start-of-page free space a little to get up to the 37603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // first live object. 37613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address free_end = StartOfLiveObject(block_address, cells[cell_index]); 37623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Free the first free space. 37633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch size = free_end - p->area_start(); 37643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch freed_bytes += space->Free(p->area_start(), 37653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(size)); 37663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The start of the current free area is represented in undigested form by 37673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the address of the last 32-word section that contained a live object and 37683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the marking bitmap for that cell, which describes where the live object 37693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // started. Unless we find a large free space in the bitmap we will not 37703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // digest this pair into a real address. We start the iteration here at the 37713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // first word in the marking bit map that indicates a live object. 37723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address free_start = block_address; 37733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t free_start_cell = cells[cell_index]; 37743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for ( ; 37763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index < last_cell_index; 37773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell_index++, block_address += 32 * kPointerSize) { 37783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((unsigned)cell_index == 37793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::IndexToCell( 37803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::CellAlignIndex( 37813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->AddressToMarkbitIndex(block_address)))); 37823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t cell = cells[cell_index]; 37833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (cell != 0) { 37843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We have a live object. Check approximately whether it is more than 32 37853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // words since the last live object. 37863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (block_address - free_start > 32 * kPointerSize) { 37873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch free_start = DigestFreeStart(free_start, free_start_cell); 37883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (block_address - free_start > 32 * kPointerSize) { 37893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Now that we know the exact start of the free space it still looks 37903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // like we have a large enough free space to be worth bothering with. 37913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // so now we need to find the start of the first live object at the 37923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // end of the free space. 37933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch free_end = StartOfLiveObject(block_address, cell); 37943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch freed_bytes += space->Free(free_start, 37953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(free_end - free_start)); 37963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 37973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 37983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update our undigested record of where the current free area started. 37993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch free_start = block_address; 38003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch free_start_cell = cell; 38013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clear marking bits for current cell. 38023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cells[cell_index] = 0; 38033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 38063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Handle the free space at the end of the page. 38073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (block_address - free_start > 32 * kPointerSize) { 38083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch free_start = DigestFreeStart(free_start, free_start_cell); 38093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch freed_bytes += space->Free(free_start, 38103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(block_address - free_start)); 38113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ResetLiveBytes(); 38143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return freed_bytes; 381585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 3816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 38193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 38203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch sweeper == LAZY_CONSERVATIVE); 3821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->ClearStats(); 3823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PageIterator it(space); 3825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t freed_bytes = 0; 38273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int pages_swept = 0; 38283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t newspace_size = space->heap()->new_space()->Size(); 38293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool lazy_sweeping_active = false; 38303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool unused_page_present = false; 383185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 38323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t old_space_size = heap()->PromotedSpaceSize(); 38333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t space_left = 38343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Min(heap()->OldGenPromotionLimit(old_space_size), 38353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->OldGenAllocationLimit(old_space_size)) - old_space_size; 383644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 38373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (it.has_next()) { 38383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* p = it.next(); 3839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clear sweeping flags indicating that marking bits are still intact. 38413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ClearSweptPrecisely(); 38423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p->ClearSweptConservatively(); 3843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (p->IsEvacuationCandidate()) { 38453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(evacuation_candidates_.length() > 0); 38463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch continue; 38473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 38503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Will be processed in EvacuateNewSpaceAndCandidates. 38513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch continue; 38523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 385385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 38543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // One unused page is kept, all further are released before sweeping them. 38553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (p->LiveBytes() == 0) { 38563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (unused_page_present) { 38573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_gc_verbose) { 38583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Sweeping 0x%" V8PRIxPTR " released page.\n", 38593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<intptr_t>(p)); 38603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Adjust unswept free bytes because releasing a page expects said 38623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // counter to be accurate for unswept pages. 38633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->IncreaseUnsweptFreeBytes(p); 38643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->ReleasePage(p); 38653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch continue; 38663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unused_page_present = true; 38683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 386985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 38703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (lazy_sweeping_active) { 38713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_gc_verbose) { 38723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Sweeping 0x%" V8PRIxPTR " lazily postponed.\n", 38733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<intptr_t>(p)); 38743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->IncreaseUnsweptFreeBytes(p); 38763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch continue; 38773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 387885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 38793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (sweeper) { 38803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CONSERVATIVE: { 38813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_gc_verbose) { 38823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 38833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<intptr_t>(p)); 38843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepConservatively(space, p); 38863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pages_swept++; 38873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 38883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case LAZY_CONSERVATIVE: { 38903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_gc_verbose) { 38913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Sweeping 0x%" V8PRIxPTR " conservatively as needed.\n", 38923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<intptr_t>(p)); 38933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch freed_bytes += SweepConservatively(space, p); 38953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pages_swept++; 38963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (space_left + freed_bytes > newspace_size) { 38973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch space->SetPagesToSweep(p->next_page()); 38983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch lazy_sweeping_active = true; 38993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 39003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_gc_verbose) { 39013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Only %" V8PRIdPTR " bytes freed. Still sweeping.\n", 39023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch freed_bytes); 39033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 39063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case PRECISE: { 39083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_gc_verbose) { 39093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n", 39103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<intptr_t>(p)); 39113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (space->identity() == CODE_SPACE) { 39133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST>(space, p, NULL); 39143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 39153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(space, p, NULL); 39163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pages_swept++; 39183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 39193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: { 39213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 39223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 392585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 392685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (FLAG_gc_verbose) { 39273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("SweepSpace: %s (%d pages swept)\n", 39283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AllocationSpaceName(space->identity()), 39293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pages_swept); 393085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 3931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Give pages that are queued to be freed back to the OS. 39333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap()->FreeQueuedChunks(); 393485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 3935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::SweepSpaces() { 39383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); 39393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 39403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch state_ = SWEEP_SPACES; 39413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 39423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweeperType how_to_sweep = 39433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; 39443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_expose_gc) how_to_sweep = CONSERVATIVE; 39453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (sweep_precisely_) how_to_sweep = PRECISE; 39463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Noncompacting collections simply sweep the spaces to clear the mark 39473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // bits and free the nonlive blocks (for old and map spaces). We sweep 39483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the map space last because freeing non-live maps overwrites them and 39493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the other spaces rely on possibly non-live maps to get the sizes for 39503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // non-live objects. 39513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepSpace(heap()->old_pointer_space(), how_to_sweep); 39523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepSpace(heap()->old_data_space(), how_to_sweep); 3953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RemoveDeadInvalidatedCode(); 39553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepSpace(heap()->code_space(), PRECISE); 3956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepSpace(heap()->cell_space(), PRECISE); 3958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EvacuateNewSpaceAndCandidates(); 3960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ClearNonLiveTransitions depends on precise sweeping of map space to 39623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // detect whether unmarked map became dead in this collection or in one 39633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // of the previous ones. 39643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SweepSpace(heap()->map_space(), PRECISE); 396585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 39663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Deallocate unmarked objects and clear marked bits for marked objects. 39673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap_->lo_space()->FreeUnmarkedObjects(); 3968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::EnableCodeFlushing(bool enable) { 39723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (enable) { 39733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (code_flusher_ != NULL) return; 39743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code_flusher_ = new CodeFlusher(heap()->isolate()); 39753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 39763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (code_flusher_ == NULL) return; 39773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch delete code_flusher_; 39783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code_flusher_ = NULL; 39793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3980592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 3981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// TODO(1466) ReportDeleteIfNeeded is not called currently. 39843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Our profiling tools do not expect intersections between 39853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// code objects. We should either reenable it or change our tools. 39863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj, 39873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate* isolate) { 39883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 39893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (obj->IsCode()) { 39903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJITInterface::RemoveCode(reinterpret_cast<Code*>(obj)); 39913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 39933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (obj->IsCode()) { 39943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate, CodeDeleteEvent(obj->address())); 39953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3996592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 3997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::Initialize() { 40003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticMarkingVisitor::Initialize(); 4001592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 4002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool SlotsBuffer::IsTypedSlot(ObjectSlot slot) { 40053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return reinterpret_cast<uintptr_t>(slot) < NUMBER_OF_SLOT_TYPES; 40063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool SlotsBuffer::AddTo(SlotsBufferAllocator* allocator, 40103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer** buffer_address, 40113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotType type, 40123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address addr, 40133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AdditionMode mode) { 40143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer* buffer = *buffer_address; 40153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (buffer == NULL || !buffer->HasSpaceForTypedSlot()) { 40163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == FAIL_ON_OVERFLOW && ChainLengthThresholdReached(buffer)) { 40173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch allocator->DeallocateChain(buffer_address); 40183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return false; 40193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer = allocator->AllocateBuffer(buffer); 40213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *buffer_address = buffer; 40223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(buffer->HasSpaceForTypedSlot()); 40243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer->Add(reinterpret_cast<ObjectSlot>(type)); 40253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer->Add(reinterpret_cast<ObjectSlot>(addr)); 40263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return true; 40273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { 40313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (RelocInfo::IsCodeTarget(rmode)) { 40323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return SlotsBuffer::CODE_TARGET_SLOT; 40333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (RelocInfo::IsEmbeddedObject(rmode)) { 40343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return SlotsBuffer::EMBEDDED_OBJECT_SLOT; 40353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (RelocInfo::IsDebugBreakSlot(rmode)) { 40363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return SlotsBuffer::DEBUG_TARGET_SLOT; 40373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (RelocInfo::IsJSReturn(rmode)) { 40383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return SlotsBuffer::JS_RETURN_SLOT; 4039592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 40403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 40413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return SlotsBuffer::NUMBER_OF_SLOT_TYPES; 40423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { 40463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); 40473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (target_page->IsEvacuationCandidate() && 40483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (rinfo->host() == NULL || 40493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { 40503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, 40513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target_page->slots_buffer_address(), 40523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotTypeForRMode(rinfo->rmode()), 40533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch rinfo->pc(), 40543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::FAIL_ON_OVERFLOW)) { 40553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EvictEvacuationCandidate(target_page); 40563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { 40623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); 40633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (target_page->IsEvacuationCandidate() && 40643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) { 40653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, 40663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target_page->slots_buffer_address(), 40673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::CODE_ENTRY_SLOT, 40683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch slot, 40693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::FAIL_ON_OVERFLOW)) { 40703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EvictEvacuationCandidate(target_page); 40713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 407485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 407585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 40763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic inline SlotsBuffer::SlotType DecodeSlotType( 40773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer::ObjectSlot slot) { 40783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return static_cast<SlotsBuffer::SlotType>(reinterpret_cast<intptr_t>(slot)); 40793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 408185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 40823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid SlotsBuffer::UpdateSlots(Heap* heap) { 40833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PointersUpdatingVisitor v(heap); 4084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) { 40863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectSlot slot = slots_[slot_idx]; 40873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IsTypedSlot(slot)) { 40883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PointersUpdatingVisitor::UpdateSlot(heap, slot); 40893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 40903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ++slot_idx; 40913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(slot_idx < idx_); 40923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UpdateSlot(&v, 40933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DecodeSlotType(slot), 40943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Address>(slots_[slot_idx])); 40953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 409685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 409785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 409885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 409985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 41003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid SlotsBuffer::UpdateSlotsWithFilter(Heap* heap) { 41013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PointersUpdatingVisitor v(heap); 41023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) { 41043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectSlot slot = slots_[slot_idx]; 41053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IsTypedSlot(slot)) { 41063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IsOnInvalidatedCodeObject(reinterpret_cast<Address>(slot))) { 41073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PointersUpdatingVisitor::UpdateSlot(heap, slot); 41083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 41093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 41103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ++slot_idx; 41113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(slot_idx < idx_); 41123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address pc = reinterpret_cast<Address>(slots_[slot_idx]); 41133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!IsOnInvalidatedCodeObject(pc)) { 41143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UpdateSlot(&v, 41153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DecodeSlotType(slot), 41163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Address>(slots_[slot_idx])); 41173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 41183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 411944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 412044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 412144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 412244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 41233ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochSlotsBuffer* SlotsBufferAllocator::AllocateBuffer(SlotsBuffer* next_buffer) { 41243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return new SlotsBuffer(next_buffer); 4125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 4126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4127756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 41283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid SlotsBufferAllocator::DeallocateBuffer(SlotsBuffer* buffer) { 41293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch delete buffer; 41308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 41318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 41328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 41333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid SlotsBufferAllocator::DeallocateChain(SlotsBuffer** buffer_address) { 41343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer* buffer = *buffer_address; 41353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (buffer != NULL) { 41363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SlotsBuffer* next_buffer = buffer->next(); 41373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeallocateBuffer(buffer); 41383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch buffer = next_buffer; 41393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 41403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *buffer_address = NULL; 4141756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 4142756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 4143756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 4144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 4145