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