12efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
71e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/atomicops.h"
8e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/base/bits.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compilation-cache.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/execution.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/gdb-jit.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/global-handles.h"
163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/incremental-marking.h"
173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/mark-compact.h"
188640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#include "src/heap/objects-visiting.h"
198640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#include "src/heap/objects-visiting-inl.h"
203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/spaces-inl.h"
213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/sweeper-thread.h"
22196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/heap-profiler.h"
23d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org#include "src/ic/ic.h"
24a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/stub-cache.h"
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
2771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
30c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* Marking::kWhiteBitPattern = "00";
31c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* Marking::kBlackBitPattern = "10";
32c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* Marking::kGreyBitPattern = "11";
33c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* Marking::kImpossibleBitPattern = "01";
34c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
35c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
36ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// -------------------------------------------------------------------------
3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// MarkCompactCollector
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgMarkCompactCollector::MarkCompactCollector(Heap* heap)
403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    :  // NOLINT
41ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#ifdef DEBUG
42ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      state_(IDLE),
43ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif
44154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      reduce_memory_footprint_(false),
45154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org      abort_incremental_marking_(false),
46e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      marking_parity_(ODD_MARKING_PARITY),
47c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      compacting_(false),
48c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      was_marked_incrementally_(false),
49d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org      sweeping_in_progress_(false),
50f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      pending_sweeper_jobs_semaphore_(0),
51750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      sequential_sweeping_(false),
52c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      migration_slots_buffer_(NULL),
53c8cbc43a1fd5fda5d6a1e172f720cbd1215157c8machenbach@chromium.org      heap_(heap),
547c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      code_flusher_(NULL),
553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      have_code_to_deoptimize_(false) {
563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
57ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
58c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass VerifyMarkingVisitor : public ObjectVisitor {
60c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public:
61c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {}
62c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
63c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void VisitPointers(Object** start, Object** end) {
64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    for (Object** current = start; current < end; current++) {
65c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if ((*current)->IsHeapObject()) {
66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        HeapObject* object = HeapObject::cast(*current);
67c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org        CHECK(heap_->mark_compact_collector()->IsMarked(object));
68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
71003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
72003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  void VisitEmbeddedPointer(RelocInfo* rinfo) {
73e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
74f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (!rinfo->host()->IsWeakObject(rinfo->target_object())) {
75057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      Object* p = rinfo->target_object();
76057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      VisitPointer(&p);
77003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
78003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
79c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
8026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  void VisitCell(RelocInfo* rinfo) {
8126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    Code* code = rinfo->host();
82e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(rinfo->rmode() == RelocInfo::CELL);
83f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (!code->IsWeakObject(rinfo->target_cell())) {
8426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      ObjectVisitor::VisitCell(rinfo);
8526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org    }
8626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org  }
8726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org
88c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org private:
89c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  Heap* heap_;
90c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com};
91c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
92c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
93c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgstatic void VerifyMarking(Heap* heap, Address bottom, Address top) {
94c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  VerifyMarkingVisitor visitor(heap);
95c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  HeapObject* object;
96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address next_object_must_be_here_or_later = bottom;
97c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (Address current = bottom; current < top; current += kPointerSize) {
99c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    object = HeapObject::FromAddress(current);
100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (MarkCompactCollector::IsMarked(object)) {
101c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org      CHECK(current >= next_object_must_be_here_or_later);
102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      object->Iterate(&visitor);
103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      next_object_must_be_here_or_later = current + object->Size();
104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyMarking(NewSpace* space) {
110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address end = space->top();
111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  NewSpacePageIterator it(space->bottom(), end);
112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The bottom position is at the start of its page. Allows us to use
113ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  // page->area_start() as start of range on all pages.
114c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  CHECK_EQ(space->bottom(),
1159d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org           NewSpacePage::FromAddress(space->bottom())->area_start());
116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    NewSpacePage* page = it.next();
118ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Address limit = it.has_next() ? page->area_end() : end;
119c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    CHECK(limit == end || !page->Contains(end));
120c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    VerifyMarking(space->heap(), page->area_start(), limit);
121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyMarking(PagedSpace* space) {
126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PageIterator it(space);
127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* p = it.next();
130c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    VerifyMarking(space->heap(), p->area_start(), p->area_end());
131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyMarking(Heap* heap) {
136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarking(heap->old_pointer_space());
137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarking(heap->old_data_space());
138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarking(heap->code_space());
139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarking(heap->cell_space());
14041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  VerifyMarking(heap->property_cell_space());
141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarking(heap->map_space());
142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarking(heap->new_space());
143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
144c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  VerifyMarkingVisitor visitor(heap);
145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  LargeObjectIterator it(heap->lo_space());
147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (MarkCompactCollector::IsMarked(obj)) {
149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      obj->Iterate(&visitor);
150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass VerifyEvacuationVisitor : public ObjectVisitor {
158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public:
159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void VisitPointers(Object** start, Object** end) {
160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    for (Object** current = start; current < end; current++) {
161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if ((*current)->IsHeapObject()) {
162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        HeapObject* object = HeapObject::cast(*current);
163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object));
164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com};
168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1709d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.orgstatic void VerifyEvacuation(Page* page) {
171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyEvacuationVisitor visitor;
1729d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  HeapObjectIterator iterator(page, NULL);
1739d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  for (HeapObject* heap_object = iterator.Next(); heap_object != NULL;
1743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org       heap_object = iterator.Next()) {
1759d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    // We skip free space objects.
1769d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    if (!heap_object->IsFiller()) {
1779d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org      heap_object->Iterate(&visitor);
178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyEvacuation(NewSpace* space) {
184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  NewSpacePageIterator it(space->bottom(), space->top());
185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyEvacuationVisitor visitor;
186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    NewSpacePage* page = it.next();
189ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Address current = page->area_start();
190ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    Address limit = it.has_next() ? page->area_end() : space->top();
191c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    CHECK(limit == space->top() || !page->Contains(space->top()));
192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    while (current < limit) {
193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HeapObject* object = HeapObject::FromAddress(current);
194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      object->Iterate(&visitor);
195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      current += object->Size();
196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2019d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.orgstatic void VerifyEvacuation(Heap* heap, PagedSpace* space) {
2029d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  if (FLAG_use_allocation_folding &&
2039d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org      (space == heap->old_pointer_space() || space == heap->old_data_space())) {
2049d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    return;
2059d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  }
206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PageIterator it(space);
207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* p = it.next();
210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (p->IsEvacuationCandidate()) continue;
2119d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    VerifyEvacuation(p);
212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void VerifyEvacuation(Heap* heap) {
2179d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  VerifyEvacuation(heap, heap->old_pointer_space());
2189d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  VerifyEvacuation(heap, heap->old_data_space());
2199d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  VerifyEvacuation(heap, heap->code_space());
2209d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  VerifyEvacuation(heap, heap->cell_space());
2219d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  VerifyEvacuation(heap, heap->property_cell_space());
2229d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  VerifyEvacuation(heap, heap->map_space());
223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyEvacuation(heap->new_space());
224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyEvacuationVisitor visitor;
226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap->IterateStrongRoots(&visitor, VISIT_ALL);
227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
228c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif  // VERIFY_HEAP
229ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
230ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
231c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef DEBUG
2323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass VerifyNativeContextSeparationVisitor : public ObjectVisitor {
233ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org public:
23446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  VerifyNativeContextSeparationVisitor() : current_native_context_(NULL) {}
235ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
236ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  void VisitPointers(Object** start, Object** end) {
237ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    for (Object** current = start; current < end; current++) {
238ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org      if ((*current)->IsHeapObject()) {
239ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org        HeapObject* object = HeapObject::cast(*current);
240ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org        if (object->IsString()) continue;
241ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org        switch (object->map()->instance_type()) {
242ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_FUNCTION_TYPE:
243ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            CheckContext(JSFunction::cast(object)->context());
244ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            break;
245ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_GLOBAL_PROXY_TYPE:
24646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            CheckContext(JSGlobalProxy::cast(object)->native_context());
247ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            break;
248ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_GLOBAL_OBJECT_TYPE:
249ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_BUILTINS_OBJECT_TYPE:
25046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org            CheckContext(GlobalObject::cast(object)->native_context());
251ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            break;
252ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_ARRAY_TYPE:
253ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_DATE_TYPE:
254ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_OBJECT_TYPE:
255ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_REGEXP_TYPE:
256ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            VisitPointer(HeapObject::RawField(object, JSObject::kMapOffset));
257ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            break;
258ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case MAP_TYPE:
259ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            VisitPointer(HeapObject::RawField(object, Map::kPrototypeOffset));
260ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            VisitPointer(HeapObject::RawField(object, Map::kConstructorOffset));
261ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            break;
262ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case FIXED_ARRAY_TYPE:
263ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            if (object->IsContext()) {
264ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org              CheckContext(object);
265ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            } else {
266ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org              FixedArray* array = FixedArray::cast(object);
267ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org              int length = array->length();
268ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org              // Set array length to zero to prevent cycles while iterating
269ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org              // over array bodies, this is easier than intrusive marking.
270ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org              array->set_length(0);
2713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              array->IterateBody(FIXED_ARRAY_TYPE, FixedArray::SizeFor(length),
2723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                 this);
273ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org              array->set_length(length);
274ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            }
275ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            break;
27641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          case CELL_TYPE:
277ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_PROXY_TYPE:
278ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case JS_VALUE_TYPE:
279ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case TYPE_FEEDBACK_INFO_TYPE:
280ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            object->Iterate(this);
281ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            break;
2827c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org          case DECLARED_ACCESSOR_INFO_TYPE:
2837c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org          case EXECUTABLE_ACCESSOR_INFO_TYPE:
284ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case BYTE_ARRAY_TYPE:
285ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case CALL_HANDLER_INFO_TYPE:
286ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case CODE_TYPE:
287ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case FIXED_DOUBLE_ARRAY_TYPE:
288ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case HEAP_NUMBER_TYPE:
28958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org          case MUTABLE_HEAP_NUMBER_TYPE:
290ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case INTERCEPTOR_INFO_TYPE:
291ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case ODDBALL_TYPE:
292ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case SCRIPT_TYPE:
293ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          case SHARED_FUNCTION_INFO_TYPE:
294ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            break;
295ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org          default:
296ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org            UNREACHABLE();
297ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org        }
298ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org      }
299ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    }
300ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  }
301ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
302ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org private:
303ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  void CheckContext(Object* context) {
304ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    if (!context->IsContext()) return;
30546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    Context* native_context = Context::cast(context)->native_context();
30646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    if (current_native_context_ == NULL) {
30746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      current_native_context_ = native_context;
308ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    } else {
30946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      CHECK_EQ(current_native_context_, native_context);
310ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    }
311ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  }
312ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
31346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* current_native_context_;
314ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org};
315ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
316ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
31746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgstatic void VerifyNativeContextSeparation(Heap* heap) {
318ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  HeapObjectIterator it(heap->code_space());
319ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
320ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  for (Object* object = it.Next(); object != NULL; object = it.Next()) {
32146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    VerifyNativeContextSeparationVisitor visitor;
322ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org    Code::cast(object)->CodeIterateBody(&visitor);
323ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  }
324ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org}
325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3286d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgvoid MarkCompactCollector::SetUp() {
3296d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  free_list_old_data_space_.Reset(new FreeList(heap_->old_data_space()));
3306d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  free_list_old_pointer_space_.Reset(new FreeList(heap_->old_pointer_space()));
3316d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org}
3326d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org
3336d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org
3343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid MarkCompactCollector::TearDown() { AbortCompaction(); }
335d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
336d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::AddEvacuationCandidate(Page* p) {
338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  p->MarkEvacuationCandidate();
339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  evacuation_candidates_.Add(p);
340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
343994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgstatic void TraceFragmentation(PagedSpace* space) {
344994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  int number_of_pages = space->CountTotalPages();
345ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  intptr_t reserved = (number_of_pages * space->AreaSize());
346994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  intptr_t free = reserved - space->SizeOfObjects();
347994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  PrintF("[%s]: %d pages, %d (%.1f%%) free\n",
3483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         AllocationSpaceName(space->identity()), number_of_pages,
3493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org         static_cast<int>(free), static_cast<double>(free) * 100 / reserved);
350994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org}
351994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
352994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
353ab7dad4f999df008b590c74c2fe3d2e2c67ef7ffjkummerow@chromium.orgbool MarkCompactCollector::StartCompaction(CompactionMode mode) {
354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!compacting_) {
355e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(evacuation_candidates_.length() == 0);
356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
35733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#ifdef ENABLE_GDB_JIT_INTERFACE
35833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    // If GDBJIT interface is active disable compaction.
35933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if (FLAG_gdbjit) return false;
36033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#endif
36133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    CollectEvacuationCandidates(heap()->old_pointer_space());
363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    CollectEvacuationCandidates(heap()->old_data_space());
364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION ||
3663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                    FLAG_incremental_code_compaction)) {
367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      CollectEvacuationCandidates(heap()->code_space());
368994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    } else if (FLAG_trace_fragmentation) {
369994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      TraceFragmentation(heap()->code_space());
370994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    }
371994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
372994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    if (FLAG_trace_fragmentation) {
373994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      TraceFragmentation(heap()->map_space());
374994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      TraceFragmentation(heap()->cell_space());
37541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      TraceFragmentation(heap()->property_cell_space());
376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists();
379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    heap()->old_data_space()->EvictEvacuationCandidatesFromFreeLists();
380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    heap()->code_space()->EvictEvacuationCandidatesFromFreeLists();
381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    compacting_ = evacuation_candidates_.length() > 0;
383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return compacting_;
386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
389061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.orgvoid MarkCompactCollector::CollectGarbage() {
390061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  // Make sure that Prepare() has been called. The individual steps below will
391061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org  // update the state as they proceed.
392e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(state_ == PREPARE_GC);
393061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
39443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  MarkLiveObjects();
395e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(heap_->incremental_marking()->IsStopped());
39643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
397003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (FLAG_collect_maps) ClearNonLiveReferences();
3989bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
399ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  ClearWeakCollections();
4007c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
401c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (FLAG_verify_heap) {
403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    VerifyMarking(heap_);
404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SweepSpaces();
40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
409ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org#ifdef DEBUG
41046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (FLAG_verify_native_context_separation) {
41146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    VerifyNativeContextSeparation(heap_);
412ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org  }
413ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org#endif
414ea52b5f5c87edc97dc0632eec996ca2af071317culan@chromium.org
41594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#ifdef VERIFY_HEAP
41625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  if (heap()->weak_embedded_objects_verification_enabled()) {
4172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    VerifyWeakEmbeddedObjectsInCode();
41894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
419594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) {
420594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    VerifyOmittedMapChecks();
4212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
42294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#endif
42394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Finish();
4257276f14ca716596e0a0d17539516370c1f453847kasper.lund
426e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  if (marking_parity_ == EVEN_MARKING_PARITY) {
427e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    marking_parity_ = ODD_MARKING_PARITY;
428e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  } else {
429e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(marking_parity_ == ODD_MARKING_PARITY);
430e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    marking_parity_ = EVEN_MARKING_PARITY;
431e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
43243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
435c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) {
437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PageIterator it(space);
438c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* p = it.next();
441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    CHECK(p->markbits()->IsClean());
442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    CHECK_EQ(0, p->LiveBytes());
443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
446c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::VerifyMarkbitsAreClean(NewSpace* space) {
448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  NewSpacePageIterator it(space->bottom(), space->top());
449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    NewSpacePage* p = it.next();
452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    CHECK(p->markbits()->IsClean());
453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    CHECK_EQ(0, p->LiveBytes());
454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
457c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::VerifyMarkbitsAreClean() {
459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarkbitsAreClean(heap_->old_pointer_space());
460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarkbitsAreClean(heap_->old_data_space());
461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarkbitsAreClean(heap_->code_space());
462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarkbitsAreClean(heap_->cell_space());
46341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  VerifyMarkbitsAreClean(heap_->property_cell_space());
464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarkbitsAreClean(heap_->map_space());
465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  VerifyMarkbitsAreClean(heap_->new_space());
466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  LargeObjectIterator it(heap_->lo_space());
468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(obj);
470c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    CHECK(Marking::IsWhite(mark_bit));
471c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes());
472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
47494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
47594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
4762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid MarkCompactCollector::VerifyWeakEmbeddedObjectsInCode() {
47794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  HeapObjectIterator code_iterator(heap()->code_space());
4783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (HeapObject* obj = code_iterator.Next(); obj != NULL;
47994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org       obj = code_iterator.Next()) {
48094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    Code* code = Code::cast(obj);
4812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (!code->is_optimized_code() && !code->is_weak_stub()) continue;
482fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (WillBeDeoptimized(code)) continue;
48325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    code->VerifyEmbeddedObjectsDependency();
48494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
48594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
4862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
488594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MarkCompactCollector::VerifyOmittedMapChecks() {
4892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  HeapObjectIterator iterator(heap()->map_space());
4903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (HeapObject* obj = iterator.Next(); obj != NULL; obj = iterator.Next()) {
4912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    Map* map = Map::cast(obj);
492594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    map->VerifyOmittedMapChecks();
4932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
4942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
495c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif  // VERIFY_HEAP
496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
498394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic void ClearMarkbitsInPagedSpace(PagedSpace* space) {
499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PageIterator it(space);
500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Bitmap::Clear(it.next());
503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
507394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic void ClearMarkbitsInNewSpace(NewSpace* space) {
508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd());
509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Bitmap::Clear(it.next());
512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
516394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid MarkCompactCollector::ClearMarkbits() {
517394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ClearMarkbitsInPagedSpace(heap_->code_space());
518394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ClearMarkbitsInPagedSpace(heap_->map_space());
519394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ClearMarkbitsInPagedSpace(heap_->old_pointer_space());
520394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ClearMarkbitsInPagedSpace(heap_->old_data_space());
521394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ClearMarkbitsInPagedSpace(heap_->cell_space());
52241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  ClearMarkbitsInPagedSpace(heap_->property_cell_space());
523394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ClearMarkbitsInNewSpace(heap_->new_space());
524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
525394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  LargeObjectIterator it(heap_->lo_space());
526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(obj);
528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    mark_bit.Clear();
529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    mark_bit.Next().Clear();
530fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    Page::FromAddress(obj->address())->ResetProgressBar();
53128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    Page::FromAddress(obj->address())->ResetLiveBytes();
532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
536f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass MarkCompactCollector::SweeperTask : public v8::Task {
537f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public:
5383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {}
539f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
540f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  virtual ~SweeperTask() {}
541f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
542f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org private:
543f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // v8::Task overrides.
544ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void Run() OVERRIDE {
54570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    heap_->mark_compact_collector()->SweepInParallel(space_, 0);
546f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    heap_->mark_compact_collector()->pending_sweeper_jobs_semaphore_.Signal();
547f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
548f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
549f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Heap* heap_;
550f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  PagedSpace* space_;
551f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
552f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  DISALLOW_COPY_AND_ASSIGN(SweeperTask);
553f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org};
554f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
555f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
556e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgvoid MarkCompactCollector::StartSweeperThreads() {
557e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(free_list_old_pointer_space_.get()->IsEmpty());
558e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(free_list_old_data_space_.get()->IsEmpty());
559d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  sweeping_in_progress_ = true;
5609af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
561876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    isolate()->sweeper_threads()[i]->StartSweeping();
562e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  }
563f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (FLAG_job_based_sweeping) {
564f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    V8::GetCurrentPlatform()->CallOnBackgroundThread(
565f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        new SweeperTask(heap(), heap()->old_data_space()),
566f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        v8::Platform::kShortRunningTask);
567f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    V8::GetCurrentPlatform()->CallOnBackgroundThread(
568f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        new SweeperTask(heap(), heap()->old_pointer_space()),
569f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        v8::Platform::kShortRunningTask);
570f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
571e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org}
572e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
573e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
574d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.orgvoid MarkCompactCollector::EnsureSweepingCompleted() {
575e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(sweeping_in_progress_ == true);
576d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org
577d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  // If sweeping is not completed, we try to complete it here. If we do not
578d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  // have sweeper threads we have to complete since we do not have a good
579d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  // indicator for a swept space in that case.
580d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  if (!AreSweeperThreadsActivated() || !IsSweepingCompleted()) {
581d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org    SweepInParallel(heap()->paged_space(OLD_DATA_SPACE), 0);
582d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org    SweepInParallel(heap()->paged_space(OLD_POINTER_SPACE), 0);
583d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  }
584d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org
5859af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
586876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    isolate()->sweeper_threads()[i]->WaitForSweeperThread();
587e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  }
588f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  if (FLAG_job_based_sweeping) {
589f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // Wait twice for both jobs.
590f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    pending_sweeper_jobs_semaphore_.Wait();
591f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    pending_sweeper_jobs_semaphore_.Wait();
592f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
593f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ParallelSweepSpacesComplete();
594d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  sweeping_in_progress_ = false;
595f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org  RefillFreeList(heap()->paged_space(OLD_DATA_SPACE));
596f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org  RefillFreeList(heap()->paged_space(OLD_POINTER_SPACE));
597750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes();
598750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes();
5999d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org
6009d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org#ifdef VERIFY_HEAP
6019d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  if (FLAG_verify_heap) {
6029d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    VerifyEvacuation(heap_);
6039d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  }
6049d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org#endif
605e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org}
606e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
607e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
6083484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgbool MarkCompactCollector::IsSweepingCompleted() {
6093484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
6103484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    if (!isolate()->sweeper_threads()[i]->SweepingCompleted()) {
6113484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      return false;
6123484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    }
6133484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  }
614d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org
6153484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (FLAG_job_based_sweeping) {
6165de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org    if (!pending_sweeper_jobs_semaphore_.WaitFor(
6175de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org            base::TimeDelta::FromSeconds(0))) {
6183484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      return false;
6193484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    }
6203484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    pending_sweeper_jobs_semaphore_.Signal();
6213484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  }
622d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org
6233484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return true;
6243484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org}
6253484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
6263484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
627f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.orgvoid MarkCompactCollector::RefillFreeList(PagedSpace* space) {
6286d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  FreeList* free_list;
6296d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org
6306d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  if (space == heap()->old_pointer_space()) {
6316d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    free_list = free_list_old_pointer_space_.get();
6326d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  } else if (space == heap()->old_data_space()) {
6336d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    free_list = free_list_old_data_space_.get();
6346d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  } else {
6356d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    // Any PagedSpace might invoke RefillFreeLists, so we need to make sure
6366d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org    // to only refill them for old data and pointer spaces.
637f05311f128ad22c89cfb6063d9375945c02239b5machenbach@chromium.org    return;
638e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  }
6396d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org
6406d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org  intptr_t freed_bytes = space->free_list()->Concatenate(free_list);
6418432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  space->AddToAccountingStats(freed_bytes);
6428432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  space->DecrementUnsweptFreeBytes(freed_bytes);
643e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org}
644e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
645e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
646e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgbool MarkCompactCollector::AreSweeperThreadsActivated() {
647f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return isolate()->sweeper_threads() != NULL || FLAG_job_based_sweeping;
648e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org}
649e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
650e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
6515697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.orgvoid Marking::TransferMark(Address old_start, Address new_start) {
652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // This is only used when resizing an object.
653e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(MemoryChunk::FromAddress(old_start) ==
654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         MemoryChunk::FromAddress(new_start));
655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6565697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  if (!heap_->incremental_marking()->IsMarking()) return;
6575697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org
658c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // If the mark doesn't move, we don't check the color of the object.
659c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // It doesn't matter whether the object is black, since it hasn't changed
660c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // size, so the adjustment to the live data count will be zero anyway.
6615697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  if (old_start == new_start) return;
662c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
663c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkBit new_mark_bit = MarkBitFrom(new_start);
664c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkBit old_mark_bit = MarkBitFrom(old_start);
665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG
667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ObjectColor old_color = Color(old_mark_bit);
668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (Marking::IsBlack(old_mark_bit)) {
671c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    old_mark_bit.Clear();
672e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsWhite(old_mark_bit));
673c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Marking::MarkBlack(new_mark_bit);
6745697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org    return;
675c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (Marking::IsGrey(old_mark_bit)) {
676c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    old_mark_bit.Clear();
677c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    old_mark_bit.Next().Clear();
678e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsWhite(old_mark_bit));
679c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    heap_->incremental_marking()->WhiteToGreyAndPush(
680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        HeapObject::FromAddress(new_start), new_mark_bit);
681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    heap_->incremental_marking()->RestartIfNotMarking();
682c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
684c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG
685c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ObjectColor new_color = Color(new_mark_bit);
686e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(new_color == old_color);
687c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
688c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comconst char* AllocationSpaceName(AllocationSpace space) {
692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  switch (space) {
6933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    case NEW_SPACE:
6943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return "NEW_SPACE";
6953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    case OLD_POINTER_SPACE:
6963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return "OLD_POINTER_SPACE";
6973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    case OLD_DATA_SPACE:
6983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return "OLD_DATA_SPACE";
6993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    case CODE_SPACE:
7003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return "CODE_SPACE";
7013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    case MAP_SPACE:
7023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return "MAP_SPACE";
7033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    case CELL_SPACE:
7043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return "CELL_SPACE";
70541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    case PROPERTY_CELL_SPACE:
70641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      return "PROPERTY_CELL_SPACE";
7073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    case LO_SPACE:
7083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return "LO_SPACE";
709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    default:
710c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      UNREACHABLE();
711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return NULL;
714c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
715c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
717994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org// Returns zero for pages that have so little fragmentation that it is not
718994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org// worth defragmenting them.  Otherwise a positive integer that gives an
719994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org// estimate of fragmentation on an arbitrary scale.
720994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.orgstatic int FreeListFragmentation(PagedSpace* space, Page* p) {
721994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  // If page was not swept then there are no free list items on it.
722994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  if (!p->WasSwept()) {
723994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    if (FLAG_trace_fragmentation) {
7243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      PrintF("%p [%s]: %d bytes live (unswept)\n", reinterpret_cast<void*>(p),
7253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org             AllocationSpaceName(space->identity()), p->LiveBytes());
726994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    }
727994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    return 0;
728994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  }
729994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
730e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  PagedSpace::SizeStats sizes;
731e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  space->ObtainFreeListStatistics(p, &sizes);
732994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
733994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  intptr_t ratio;
734994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  intptr_t ratio_threshold;
735ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  intptr_t area_size = space->AreaSize();
736994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  if (space->identity() == CODE_SPACE) {
7373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / area_size;
738994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    ratio_threshold = 10;
739994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  } else {
7403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / area_size;
741994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    ratio_threshold = 15;
742994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  }
743994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
744994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  if (FLAG_trace_fragmentation) {
745994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    PrintF("%p [%s]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n",
7463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           reinterpret_cast<void*>(p), AllocationSpaceName(space->identity()),
747994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org           static_cast<int>(sizes.small_size_),
7483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           static_cast<double>(sizes.small_size_ * 100) / area_size,
749994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org           static_cast<int>(sizes.medium_size_),
7503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           static_cast<double>(sizes.medium_size_ * 100) / area_size,
751994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org           static_cast<int>(sizes.large_size_),
7523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           static_cast<double>(sizes.large_size_ * 100) / area_size,
753994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org           static_cast<int>(sizes.huge_size_),
7543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           static_cast<double>(sizes.huge_size_ * 100) / area_size,
755994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org           (ratio > ratio_threshold) ? "[fragmented]" : "");
756994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  }
757994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
758ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  if (FLAG_always_compact && sizes.Total() != area_size) {
759994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    return 1;
760994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  }
761994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
762994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  if (ratio <= ratio_threshold) return 0;  // Not fragmented.
763994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
764994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  return static_cast<int>(ratio - ratio_threshold);
765994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org}
766994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
767994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
768c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
769e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(space->identity() == OLD_POINTER_SPACE ||
770c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         space->identity() == OLD_DATA_SPACE ||
771c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com         space->identity() == CODE_SPACE);
772c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
773de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  static const int kMaxMaxEvacuationCandidates = 1000;
7741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int number_of_pages = space->CountTotalPages();
775de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  int max_evacuation_candidates =
776e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      static_cast<int>(std::sqrt(number_of_pages / 2.0) + 1);
7771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
7781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (FLAG_stress_compaction || FLAG_always_compact) {
7791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    max_evacuation_candidates = kMaxMaxEvacuationCandidates;
7801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
7811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
7821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  class Candidate {
7831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org   public:
7843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Candidate() : fragmentation_(0), page_(NULL) {}
7853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Candidate(int f, Page* p) : fragmentation_(f), page_(p) {}
7861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
7871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    int fragmentation() { return fragmentation_; }
7881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    Page* page() { return page_; }
7891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
7901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org   private:
7911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    int fragmentation_;
7921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    Page* page_;
7931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  };
7941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
7953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  enum CompactionMode { COMPACT_FREE_LISTS, REDUCE_MEMORY_FOOTPRINT };
796994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
797994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  CompactionMode mode = COMPACT_FREE_LISTS;
798994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
799ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  intptr_t reserved = number_of_pages * space->AreaSize();
800994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  intptr_t over_reserved = reserved - space->SizeOfObjects();
801994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  static const intptr_t kFreenessThreshold = 50;
802994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
803471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  if (reduce_memory_footprint_ && over_reserved >= space->AreaSize()) {
804de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // If reduction of memory footprint was requested, we are aggressive
805de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // about choosing pages to free.  We expect that half-empty pages
806de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // are easier to compact so slightly bump the limit.
807471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    mode = REDUCE_MEMORY_FOOTPRINT;
808471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    max_evacuation_candidates += 2;
809471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  }
810471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
811994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
812471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  if (over_reserved > reserved / 3 && over_reserved >= 2 * space->AreaSize()) {
813de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // If over-usage is very high (more than a third of the space), we
814de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // try to free all mostly empty pages.  We expect that almost empty
815de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org    // pages are even easier to compact so bump the limit even more.
816471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    mode = REDUCE_MEMORY_FOOTPRINT;
817471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org    max_evacuation_candidates *= 2;
818471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  }
819994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
820471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  if (FLAG_trace_fragmentation && mode == REDUCE_MEMORY_FOOTPRINT) {
8213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    PrintF(
8223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        "Estimated over reserved memory: %.1f / %.1f MB (threshold %d), "
8233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        "evacuation candidate limit: %d\n",
8243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        static_cast<double>(over_reserved) / MB,
8253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        static_cast<double>(reserved) / MB,
8263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        static_cast<int>(kFreenessThreshold), max_evacuation_candidates);
827994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  }
828994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
829994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  intptr_t estimated_release = 0;
830994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
8311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Candidate candidates[kMaxMaxEvacuationCandidates];
8321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
833de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org  max_evacuation_candidates =
834de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org      Min(kMaxMaxEvacuationCandidates, max_evacuation_candidates);
835de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org
836c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int count = 0;
8371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int fragmentation = 0;
8381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  Candidate* least = NULL;
839994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
840994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  PageIterator it(space);
841994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org  if (it.has_next()) it.next();  // Never compact the first page.
842994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
843c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
844c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* p = it.next();
8451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    p->ClearEvacuationCandidate();
846994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
847b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    if (FLAG_stress_compaction) {
848b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org      unsigned int counter = space->heap()->ms_count();
849b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      uintptr_t page_number = reinterpret_cast<uintptr_t>(p) >> kPageSizeBits;
8501b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      if ((counter & 1) == (page_number & 1)) fragmentation = 1;
851994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    } else if (mode == REDUCE_MEMORY_FOOTPRINT) {
852994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      // Don't try to release too many pages.
853bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      if (estimated_release >= over_reserved) {
854994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org        continue;
855994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      }
856994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
857994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      intptr_t free_bytes = 0;
858994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
859994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      if (!p->WasSwept()) {
860ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org        free_bytes = (p->area_size() - p->LiveBytes());
861994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      } else {
862e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        PagedSpace::SizeStats sizes;
863e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        space->ObtainFreeListStatistics(p, &sizes);
864994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org        free_bytes = sizes.Total();
865994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      }
866994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
867ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      int free_pct = static_cast<int>(free_bytes * 100) / p->area_size();
868994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
869994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      if (free_pct >= kFreenessThreshold) {
870bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        estimated_release += free_bytes;
871994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org        fragmentation = free_pct;
872994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      } else {
873994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org        fragmentation = 0;
874994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      }
875994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
876994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      if (FLAG_trace_fragmentation) {
8773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        PrintF("%p [%s]: %d (%.2f%%) free %s\n", reinterpret_cast<void*>(p),
878994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org               AllocationSpaceName(space->identity()),
879994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org               static_cast<int>(free_bytes),
880ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org               static_cast<double>(free_bytes * 100) / p->area_size(),
881994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org               (fragmentation > 0) ? "[fragmented]" : "");
882994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      }
883b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    } else {
884994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org      fragmentation = FreeListFragmentation(space, p);
885b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
886994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
8871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (fragmentation != 0) {
8881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      if (count < max_evacuation_candidates) {
8891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        candidates[count++] = Candidate(fragmentation, p);
8901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      } else {
8911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (least == NULL) {
8921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          for (int i = 0; i < max_evacuation_candidates; i++) {
8931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            if (least == NULL ||
8941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                candidates[i].fragmentation() < least->fragmentation()) {
8951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org              least = candidates + i;
8961b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            }
8971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          }
8981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
8991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (least->fragmentation() < fragmentation) {
9001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          *least = Candidate(fragmentation, p);
9011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          least = NULL;
9021b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
9031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      }
904c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
905c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
906994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org
9071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  for (int i = 0; i < count; i++) {
9081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    AddEvacuationCandidate(candidates[i].page());
9091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
910c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (count > 0 && FLAG_trace_fragmentation) {
9123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    PrintF("Collected %d evacuation candidates for space %s\n", count,
913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           AllocationSpaceName(space->identity()));
914c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
918c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::AbortCompaction() {
919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (compacting_) {
920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int npages = evacuation_candidates_.length();
921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    for (int i = 0; i < npages; i++) {
922c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Page* p = evacuation_candidates_[i];
923c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address());
924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      p->ClearEvacuationCandidate();
925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
927c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    compacting_ = false;
928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    evacuation_candidates_.Rewind(0);
929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    invalidated_code_.Rewind(0);
930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
931e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0, evacuation_candidates_.length());
932c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
933c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
935474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgvoid MarkCompactCollector::Prepare() {
936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  was_marked_incrementally_ = heap()->incremental_marking()->IsMarking();
937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
939e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(state_ == IDLE);
94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  state_ = PREPARE_GC;
94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
94243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
943e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!FLAG_never_compact || !FLAG_always_compact);
94443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
945d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  if (sweeping_in_progress()) {
946e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org    // Instead of waiting we could also abort the sweeper threads here.
947d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org    EnsureSweepingCompleted();
948e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  }
949e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
950bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  // Clear marking bits if incremental marking is aborted.
951bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  if (was_marked_incrementally_ && abort_incremental_marking_) {
952c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    heap()->incremental_marking()->Abort();
953394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ClearMarkbits();
9543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    AbortWeakCollections();
955c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    AbortCompaction();
956c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    was_marked_incrementally_ = false;
957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
958c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Don't start compaction if we are in the middle of incremental
960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // marking cycle. We did not collect any slots.
961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!FLAG_never_compact && !was_marked_incrementally_) {
962ab7dad4f999df008b590c74c2fe3d2e2c67ef7ffjkummerow@chromium.org    StartCompaction(NON_INCREMENTAL_COMPACTION);
963c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
964c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
9657c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  PagedSpaces spaces(heap());
9663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (PagedSpace* space = spaces.next(); space != NULL;
967c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       space = spaces.next()) {
968c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    space->PrepareForMarkCompact();
969c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
970c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
971c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
972394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (!was_marked_incrementally_ && FLAG_verify_heap) {
973c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    VerifyMarkbitsAreClean();
9749258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
975c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
97643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
97743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
97943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid MarkCompactCollector::Finish() {
98043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
981e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(state_ == SWEEP_SPACES || state_ == RELOCATE_OBJECTS);
98243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  state_ = IDLE;
98343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
98443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The stub cache is not traversed during GC; clear the cache to
98543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // force lazy re-initialization of it. This must be done after the
98643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // GC, because it relies on the new address of certain old space
98743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // objects (empty string, illegal builtin).
988876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  isolate()->stub_cache()->Clear();
989003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
9903d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  if (have_code_to_deoptimize_) {
9913d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    // Some code objects were marked for deoptimization during the GC.
9923d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    Deoptimizer::DeoptimizeMarkedCode(isolate());
9933d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    have_code_to_deoptimize_ = false;
994fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  }
99543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
99643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
99743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
998ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// -------------------------------------------------------------------------
99943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Phase 1: tracing and marking live objects.
100043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//   before: all objects are in normal state.
100143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//   after: a live object's map pointer is marked as '00'.
100243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
100343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Marking all live objects in the heap as part of mark-sweep or mark-compact
100443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// collection.  Before marking, all objects are in their normal state.  After
100543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// marking, live objects' map pointers are marked indicating that the object
100643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// has been found reachable.
100743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
100843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The marking algorithm is a (mostly) depth-first (because of possible stack
100943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// overflow) traversal of the graph of objects reachable from the roots.  It
101043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// uses an explicit stack of pointers rather than recursion.  The young
101143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// generation's inactive ('from') space is used as a marking stack.  The
101243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// objects in the marking stack are the ones that have been reached and marked
101343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// but their children have not yet been visited.
101443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
101543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The marking stack can overflow during traversal.  In that case, we set an
101643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// overflow flag.  When the overflow flag is set, we continue marking objects
101743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// reachable from the objects on the marking stack, but no longer push them on
101843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the marking stack.  Instead, we mark them as both marked and overflowed.
101943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// When the stack is in the overflowed state, objects marked as overflowed
102043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// have been reached and marked but their children have not been visited yet.
102143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// After emptying the marking stack, we clear the overflow flag and traverse
102243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the heap looking for objects marked as overflowed, push them on the stack,
102343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// and continue with marking.  This process repeats until all reachable
102443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// objects have been marked.
102543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1026c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid CodeFlusher::ProcessJSFunctionCandidates() {
1027a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy);
102889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  Object* undefined = isolate_->heap()->undefined_value();
1029a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1030c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  JSFunction* candidate = jsfunction_candidates_head_;
1031c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  JSFunction* next_candidate;
1032c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  while (candidate != NULL) {
1033c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    next_candidate = GetNextCandidate(candidate);
103489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    ClearNextCandidate(candidate, undefined);
1035a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1036c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    SharedFunctionInfo* shared = candidate->shared();
1037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1038c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Code* code = shared->code();
1039c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    MarkBit code_mark = Marking::MarkBitFrom(code);
1040c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    if (!code_mark.Get()) {
1041837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org      if (FLAG_trace_code_flushing && shared->is_compiled()) {
1042b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("[code-flushing clears: ");
1043b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        shared->ShortPrint();
1044b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF(" - age: %d]\n", code->GetAge());
1045837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org      }
1046c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org      shared->set_code(lazy_compile);
1047c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org      candidate->set_code(lazy_compile);
10489768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org    } else {
10499768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org      candidate->set_code(code);
1050a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
1051a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1052c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    // We are in the middle of a GC cycle so the write barrier in the code
1053c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    // setter did not record the slot update and we have to do that manually.
1054c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Address slot = candidate->address() + JSFunction::kCodeEntryOffset;
1055c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot));
10563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->heap()->mark_compact_collector()->RecordCodeEntrySlot(slot,
10573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                                    target);
1058b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org
1059c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Object** shared_code_slot =
1060c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org        HeapObject::RawField(shared, SharedFunctionInfo::kCodeOffset);
10613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->heap()->mark_compact_collector()->RecordSlot(
10623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        shared_code_slot, shared_code_slot, *shared_code_slot);
1063a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1064c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    candidate = next_candidate;
1065a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1066a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1067c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  jsfunction_candidates_head_ = NULL;
1068c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org}
1069b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org
1070a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1071c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid CodeFlusher::ProcessSharedFunctionInfoCandidates() {
1072a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy);
1073a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1074c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
1075c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  SharedFunctionInfo* next_candidate;
1076c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  while (candidate != NULL) {
1077c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    next_candidate = GetNextCandidate(candidate);
107889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    ClearNextCandidate(candidate);
1079a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
108064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    Code* code = candidate->code();
1081c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    MarkBit code_mark = Marking::MarkBitFrom(code);
1082c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    if (!code_mark.Get()) {
1083837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org      if (FLAG_trace_code_flushing && candidate->is_compiled()) {
1084b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF("[code-flushing clears: ");
1085b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        candidate->ShortPrint();
1086b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org        PrintF(" - age: %d]\n", code->GetAge());
1087837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org      }
1088c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org      candidate->set_code(lazy_compile);
1089c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    }
1090a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1091c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    Object** code_slot =
1092c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org        HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset);
10933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    isolate_->heap()->mark_compact_collector()->RecordSlot(code_slot, code_slot,
10943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                           *code_slot);
1095a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1096c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org    candidate = next_candidate;
1097a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1098a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1099c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  shared_function_info_candidates_head_ = NULL;
1100c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org}
1101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
11034e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid CodeFlusher::ProcessOptimizedCodeMaps() {
11044954674151afa960af66efb4831df06bde727333yangguo@chromium.org  STATIC_ASSERT(SharedFunctionInfo::kEntryLength == 4);
11054e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
11064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  SharedFunctionInfo* holder = optimized_code_map_holder_head_;
11074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  SharedFunctionInfo* next_holder;
11084954674151afa960af66efb4831df06bde727333yangguo@chromium.org
11094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  while (holder != NULL) {
11104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    next_holder = GetNextCodeMap(holder);
11114e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    ClearNextCodeMap(holder);
11124e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
11134e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    FixedArray* code_map = FixedArray::cast(holder->optimized_code_map());
11144954674151afa960af66efb4831df06bde727333yangguo@chromium.org    int new_length = SharedFunctionInfo::kEntriesStart;
11154e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    int old_length = code_map->length();
11163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    for (int i = SharedFunctionInfo::kEntriesStart; i < old_length;
11174954674151afa960af66efb4831df06bde727333yangguo@chromium.org         i += SharedFunctionInfo::kEntryLength) {
11184954674151afa960af66efb4831df06bde727333yangguo@chromium.org      Code* code =
11194954674151afa960af66efb4831df06bde727333yangguo@chromium.org          Code::cast(code_map->get(i + SharedFunctionInfo::kCachedCodeOffset));
11204954674151afa960af66efb4831df06bde727333yangguo@chromium.org      if (!Marking::MarkBitFrom(code).Get()) continue;
11214954674151afa960af66efb4831df06bde727333yangguo@chromium.org
11224954674151afa960af66efb4831df06bde727333yangguo@chromium.org      // Move every slot in the entry.
11234954674151afa960af66efb4831df06bde727333yangguo@chromium.org      for (int j = 0; j < SharedFunctionInfo::kEntryLength; j++) {
11244954674151afa960af66efb4831df06bde727333yangguo@chromium.org        int dst_index = new_length++;
11254954674151afa960af66efb4831df06bde727333yangguo@chromium.org        Object** slot = code_map->RawFieldOfElementAt(dst_index);
11264954674151afa960af66efb4831df06bde727333yangguo@chromium.org        Object* object = code_map->get(i + j);
11274954674151afa960af66efb4831df06bde727333yangguo@chromium.org        code_map->set(dst_index, object);
11284954674151afa960af66efb4831df06bde727333yangguo@chromium.org        if (j == SharedFunctionInfo::kOsrAstIdOffset) {
1129e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(object->IsSmi());
11304954674151afa960af66efb4831df06bde727333yangguo@chromium.org        } else {
11313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          DCHECK(
11323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              Marking::IsBlack(Marking::MarkBitFrom(HeapObject::cast(*slot))));
11333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          isolate_->heap()->mark_compact_collector()->RecordSlot(slot, slot,
11343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                                 *slot);
11354954674151afa960af66efb4831df06bde727333yangguo@chromium.org        }
11364e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      }
11374e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    }
11384e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
11394e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // Trim the optimized code map if entries have been removed.
11404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    if (new_length < old_length) {
11414e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      holder->TrimOptimizedCodeMap(old_length - new_length);
11424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    }
11434e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
11444e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    holder = next_holder;
11454e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
11464e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
11474e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  optimized_code_map_holder_head_ = NULL;
11484e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
11494e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
11504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
11519768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.orgvoid CodeFlusher::EvictCandidate(SharedFunctionInfo* shared_info) {
1152c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org  // Make sure previous flushing decisions are revisited.
11539768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org  isolate_->heap()->incremental_marking()->RecordWrites(shared_info);
11549768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org
1155837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  if (FLAG_trace_code_flushing) {
1156b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    PrintF("[code-flushing abandons function-info: ");
1157b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    shared_info->ShortPrint();
1158b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    PrintF("]\n");
1159837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  }
1160837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org
11619768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org  SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
11629768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org  SharedFunctionInfo* next_candidate;
11639768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org  if (candidate == shared_info) {
11649768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org    next_candidate = GetNextCandidate(shared_info);
11659768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org    shared_function_info_candidates_head_ = next_candidate;
11669768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org    ClearNextCandidate(shared_info);
11679768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org  } else {
11689768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org    while (candidate != NULL) {
11699768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org      next_candidate = GetNextCandidate(candidate);
11709768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org
11719768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org      if (next_candidate == shared_info) {
11729768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org        next_candidate = GetNextCandidate(shared_info);
11739768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org        SetNextCandidate(candidate, next_candidate);
11749768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org        ClearNextCandidate(shared_info);
11759768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org        break;
11769768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org      }
11779768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org
11789768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org      candidate = next_candidate;
11799768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org    }
11809768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org  }
11819768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org}
11829768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org
11839768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org
1184e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid CodeFlusher::EvictCandidate(JSFunction* function) {
1185e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!function->next_function_link()->IsUndefined());
1186e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Object* undefined = isolate_->heap()->undefined_value();
1187e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1188c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org  // Make sure previous flushing decisions are revisited.
118932280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org  isolate_->heap()->incremental_marking()->RecordWrites(function);
1190c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org  isolate_->heap()->incremental_marking()->RecordWrites(function->shared());
119132280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org
1192837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  if (FLAG_trace_code_flushing) {
1193b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    PrintF("[code-flushing abandons closure: ");
1194b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    function->shared()->ShortPrint();
1195b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    PrintF("]\n");
1196837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  }
1197837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org
1198e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  JSFunction* candidate = jsfunction_candidates_head_;
1199e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  JSFunction* next_candidate;
1200e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (candidate == function) {
1201e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    next_candidate = GetNextCandidate(function);
1202e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    jsfunction_candidates_head_ = next_candidate;
1203e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    ClearNextCandidate(function, undefined);
1204e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  } else {
1205e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    while (candidate != NULL) {
1206e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      next_candidate = GetNextCandidate(candidate);
1207e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1208e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      if (next_candidate == function) {
1209e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        next_candidate = GetNextCandidate(function);
1210e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        SetNextCandidate(candidate, next_candidate);
1211e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org        ClearNextCandidate(function, undefined);
12129768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org        break;
1213e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      }
1214e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1215e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      candidate = next_candidate;
1216e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
1217e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
1218e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
1219e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1220e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
12214e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid CodeFlusher::EvictOptimizedCodeMap(SharedFunctionInfo* code_map_holder) {
12223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(!FixedArray::cast(code_map_holder->optimized_code_map())
12233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              ->get(SharedFunctionInfo::kNextMapIndex)
12243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              ->IsUndefined());
12254e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
12264e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // Make sure previous flushing decisions are revisited.
12274e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  isolate_->heap()->incremental_marking()->RecordWrites(code_map_holder);
12284e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
1229837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  if (FLAG_trace_code_flushing) {
1230b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    PrintF("[code-flushing abandons code-map: ");
1231b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    code_map_holder->ShortPrint();
1232b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    PrintF("]\n");
1233837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  }
1234837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org
12354e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  SharedFunctionInfo* holder = optimized_code_map_holder_head_;
12364e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  SharedFunctionInfo* next_holder;
12374e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (holder == code_map_holder) {
12384e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    next_holder = GetNextCodeMap(code_map_holder);
12394e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    optimized_code_map_holder_head_ = next_holder;
12404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    ClearNextCodeMap(code_map_holder);
12414e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  } else {
12424e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    while (holder != NULL) {
12434e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      next_holder = GetNextCodeMap(holder);
12444e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
12454e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      if (next_holder == code_map_holder) {
12464e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org        next_holder = GetNextCodeMap(code_map_holder);
12474e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org        SetNextCodeMap(holder, next_holder);
12484e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org        ClearNextCodeMap(code_map_holder);
12494e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org        break;
12504e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      }
12514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
12524e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org      holder = next_holder;
12534e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    }
12544e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
12554e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
12564e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
12574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
1258e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid CodeFlusher::EvictJSFunctionCandidates() {
1259e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  JSFunction* candidate = jsfunction_candidates_head_;
1260e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  JSFunction* next_candidate;
1261e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  while (candidate != NULL) {
1262e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    next_candidate = GetNextCandidate(candidate);
12637c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    EvictCandidate(candidate);
1264e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    candidate = next_candidate;
1265e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
1266e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(jsfunction_candidates_head_ == NULL);
1267e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
1268e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1269e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1270e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid CodeFlusher::EvictSharedFunctionInfoCandidates() {
1271e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
1272e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  SharedFunctionInfo* next_candidate;
1273e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  while (candidate != NULL) {
1274e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    next_candidate = GetNextCandidate(candidate);
12757c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    EvictCandidate(candidate);
1276e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    candidate = next_candidate;
1277e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
1278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(shared_function_info_candidates_head_ == NULL);
1279e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org}
1280e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
1281e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
12824e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.orgvoid CodeFlusher::EvictOptimizedCodeMaps() {
12834e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  SharedFunctionInfo* holder = optimized_code_map_holder_head_;
12844e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  SharedFunctionInfo* next_holder;
12854e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  while (holder != NULL) {
12864e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    next_holder = GetNextCodeMap(holder);
12874e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    EvictOptimizedCodeMap(holder);
12884e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    holder = next_holder;
12894e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
1290e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(optimized_code_map_holder_head_ == NULL);
12914e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org}
12924e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
12934e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
1294e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgvoid CodeFlusher::IteratePointersToFromSpace(ObjectVisitor* v) {
1295e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  Heap* heap = isolate_->heap();
1296e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1297e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  JSFunction** slot = &jsfunction_candidates_head_;
1298e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  JSFunction* candidate = jsfunction_candidates_head_;
1299e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  while (candidate != NULL) {
1300e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (heap->InFromSpace(candidate)) {
1301e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      v->VisitPointer(reinterpret_cast<Object**>(slot));
1302e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
1303e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    candidate = GetNextCandidate(*slot);
1304e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    slot = GetNextCandidateSlot(*slot);
1305e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
1306e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org}
1307e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1308e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
1309ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgMarkCompactCollector::~MarkCompactCollector() {
1310ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (code_flusher_ != NULL) {
1311ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    delete code_flusher_;
1312ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    code_flusher_ = NULL;
1313ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
1314ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
1315ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
131631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
13175a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgstatic inline HeapObject* ShortCircuitConsString(Object** p) {
13184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Optimization: If the heap object pointed to by p is a non-internalized
1319ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // cons string whose right substring is HEAP->empty_string, update
13209258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // it in place to its left substring.  Return the updated value.
132131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  //
132231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  // Here we assume that if we change *p, we replace it with a heap object
13232efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // (i.e., the left substring of a cons string is always a heap object).
132431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  //
132531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  // The check performed is:
13264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  //   object->IsConsString() && !object->IsInternalizedString() &&
1327ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  //   (ConsString::cast(object)->second() == HEAP->empty_string())
132831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  // except the maps for the object and its possible substrings might be
132931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  // marked.
133031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  HeapObject* object = HeapObject::cast(*p);
1331b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  if (!FLAG_clever_optimizations) return object;
1332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Map* map = object->map();
1333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  InstanceType type = map->instance_type();
1334d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org  if (!IsShortcutCandidate(type)) return object;
133531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
13361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Object* second = reinterpret_cast<ConsString*>(object)->second();
1337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Heap* heap = map->GetHeap();
1338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (second != heap->empty_string()) {
133968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    return object;
134068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  }
134131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
134231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  // Since we don't have the object's start, it is impossible to update the
134330ce411529579186181838984710b0b0980857aaricow@chromium.org  // page dirty marks. Therefore, we only replace the string with its left
134430ce411529579186181838984710b0b0980857aaricow@chromium.org  // substring when page dirty marks do not change.
13451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Object* first = reinterpret_cast<ConsString*>(object)->first();
1346ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (!heap->InNewSpace(object) && heap->InNewSpace(first)) return object;
134731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
134831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  *p = first;
134931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  return HeapObject::cast(first);
135031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager}
135131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
135231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
1353b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor
1354b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    : public StaticMarkingVisitor<MarkCompactMarkingVisitor> {
135543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
13563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id, Map* map,
13573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   HeapObject* obj);
1358304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
1359304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  static void ObjectStatsCountFixedArray(
13603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type,
1361304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      FixedArraySubInstanceType dictionary_type);
1362304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
13633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  template <MarkCompactMarkingVisitor::VisitorId id>
136428583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  class ObjectStatsTracker {
136528583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org   public:
1366753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    static inline void Visit(Map* map, HeapObject* obj);
136728583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  };
136828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org
1369753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  static void Initialize();
1370ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1371ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  INLINE(static void VisitPointer(Heap* heap, Object** p)) {
1372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkObjectByPointer(heap->mark_compact_collector(), p, p);
137343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
137443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13752ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) {
137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Mark all objects pointed to in [start, end).
137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    const int kMinRangeForMarkingRecursion = 64;
137843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (end - start >= kMinRangeForMarkingRecursion) {
13792ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org      if (VisitUnmarkedObjects(heap, start, end)) return;
138043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // We are close to a stack overflow, so just mark the objects.
138143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
1382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkCompactCollector* collector = heap->mark_compact_collector();
1383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    for (Object** p = start; p < end; p++) {
13842ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org      MarkObjectByPointer(collector, start, p);
13857a96c2a24221ccb98eb3fbe4f5618ef9076cf55fjkummerow@chromium.org    }
13867a96c2a24221ccb98eb3fbe4f5618ef9076cf55fjkummerow@chromium.org  }
13877a96c2a24221ccb98eb3fbe4f5618ef9076cf55fjkummerow@chromium.org
138833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  // Marks the object black and pushes it on the marking stack.
1389b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  INLINE(static void MarkObject(Heap* heap, HeapObject* object)) {
1390b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    MarkBit mark = Marking::MarkBitFrom(object);
1391b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    heap->mark_compact_collector()->MarkObject(object, mark);
1392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
139433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  // Marks the object black without pushing it on the marking stack.
139533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  // Returns true if object needed marking and false otherwise.
139633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) {
139733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    MarkBit mark_bit = Marking::MarkBitFrom(object);
139833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if (!mark_bit.Get()) {
139933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      heap->mark_compact_collector()->SetMark(object, mark_bit);
140033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      return true;
140133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    }
140233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    return false;
140333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  }
140433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
140543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Mark object pointed to by p.
1406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector,
14073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                         Object** anchor_slot, Object** p)) {
140831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    if (!(*p)->IsHeapObject()) return;
140931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    HeapObject* object = ShortCircuitConsString(p);
1410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    collector->RecordSlot(anchor_slot, p, object);
1411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark = Marking::MarkBitFrom(object);
1412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    collector->MarkObject(object, mark);
141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
141443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1415ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Visit an unmarked object.
1417c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector,
1418c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org                                         HeapObject* obj)) {
141943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
1420e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(collector->heap()->Contains(obj));
1421e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!collector->heap()->mark_compact_collector()->IsMarked(obj));
142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
142343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Map* map = obj->map();
1424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Heap* heap = obj->GetHeap();
1425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark = Marking::MarkBitFrom(obj);
1426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    heap->mark_compact_collector()->SetMark(obj, mark);
142743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Mark the map pointer and the body.
1428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit map_mark = Marking::MarkBitFrom(map);
1429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    heap->mark_compact_collector()->MarkObject(map, map_mark);
1430ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org    IterateBody(map, obj);
143143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
143243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14332ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  // Visit all unmarked objects pointed to by [start, end).
143443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Returns false if the operation fails (lack of stack space).
14353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  INLINE(static bool VisitUnmarkedObjects(Heap* heap, Object** start,
14362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                          Object** end)) {
143743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Return false is we are close to the stack limit.
1438ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    StackLimitCheck check(heap->isolate());
143943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (check.HasOverflowed()) return false;
144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1441c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    MarkCompactCollector* collector = heap->mark_compact_collector();
144243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Visit the unmarked objects.
14432ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    for (Object** p = start; p < end; p++) {
1444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object* o = *p;
1445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (!o->IsHeapObject()) continue;
14462ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org      collector->RecordSlot(start, p, o);
1447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HeapObject* obj = HeapObject::cast(o);
1448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      MarkBit mark = Marking::MarkBitFrom(obj);
1449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (mark.Get()) continue;
1450c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      VisitUnmarkedObject(collector, obj);
145143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
145243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return true;
145343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1454ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1455b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org private:
14563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  template <int id>
1457b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj);
1458ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
14590b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // Code flushing support.
14600b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
1461ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  static const int kRegExpCodeThreshold = 5;
1462ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
14633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  static void UpdateRegExpCodeAgeAndFlush(Heap* heap, JSRegExp* re,
14642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                          bool is_one_byte) {
1465ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    // Make sure that the fixed array is in fact initialized on the RegExp.
1466ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    // We could potentially trigger a GC when initializing the RegExp.
1467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (HeapObject::cast(re->data())->map()->instance_type() !=
14683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        FIXED_ARRAY_TYPE)
14693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      return;
1470ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
1471ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    // Make sure this is a RegExp that actually contains code.
1472b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (re->TypeTag() != JSRegExp::IRREGEXP) return;
1473ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
14742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    Object* code = re->DataAt(JSRegExp::code_index(is_one_byte));
1475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!code->IsSmi() &&
1476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        HeapObject::cast(code)->map()->instance_type() == CODE_TYPE) {
1477ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      // Save a copy that can be reinstated if we need the code again.
14782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      re->SetDataAt(JSRegExp::saved_code_index(is_one_byte), code);
147978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
148078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // Saving a copy might create a pointer into compaction candidate
148178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // that was not observed by marker.  This might happen if JSRegExp data
148278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // was marked through the compilation cache before marker reached JSRegExp
148378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      // object.
148478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      FixedArray* data = FixedArray::cast(re->data());
14852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      Object** slot =
14862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org          data->data_start() + JSRegExp::saved_code_index(is_one_byte);
14873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      heap->mark_compact_collector()->RecordSlot(slot, slot, code);
148878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
1489ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      // Set a number in the 0-255 range to guarantee no smi overflow.
14902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      re->SetDataAt(JSRegExp::code_index(is_one_byte),
1491b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                    Smi::FromInt(heap->sweep_generation() & 0xff));
1492ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    } else if (code->IsSmi()) {
1493ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      int value = Smi::cast(code)->value();
1494ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      // The regexp has not been compiled yet or there was a compilation error.
1495ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      if (value == JSRegExp::kUninitializedValue ||
1496ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org          value == JSRegExp::kCompilationErrorValue) {
1497ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org        return;
1498ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      }
1499ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
1500ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      // Check if we should flush now.
1501ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      if (value == ((heap->sweep_generation() - kRegExpCodeThreshold) & 0xff)) {
15022c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        re->SetDataAt(JSRegExp::code_index(is_one_byte),
1503b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                      Smi::FromInt(JSRegExp::kUninitializedValue));
15042c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        re->SetDataAt(JSRegExp::saved_code_index(is_one_byte),
1505b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                      Smi::FromInt(JSRegExp::kUninitializedValue));
1506ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      }
1507ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    }
1508ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  }
1509ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
1510ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
1511ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // Works by setting the current sweep_generation (as a smi) in the
1512ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // code object place in the data array of the RegExp and keeps a copy
1513ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // around that can be reinstated if we reuse the RegExp before flushing.
1514ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // If we did not use the code for kRegExpCodeThreshold mark sweep GCs
1515ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // we flush the code.
1516ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  static void VisitRegExpAndFlushCode(Map* map, HeapObject* object) {
1517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Heap* heap = map->GetHeap();
1518ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    MarkCompactCollector* collector = heap->mark_compact_collector();
1519ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    if (!collector->is_code_flushing_enabled()) {
1520b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org      VisitJSRegExp(map, object);
1521ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      return;
1522ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    }
1523ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    JSRegExp* re = reinterpret_cast<JSRegExp*>(object);
15242c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    // Flush code or set age on both one byte and two byte code.
1525ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    UpdateRegExpCodeAgeAndFlush(heap, re, true);
1526ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    UpdateRegExpCodeAgeAndFlush(heap, re, false);
1527ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    // Visit the fields of the RegExp, including the updated FixedArray.
1528b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    VisitJSRegExp(map, object);
1529ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  }
1530ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
153128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  static VisitorDispatchTable<Callback> non_count_table_;
1532ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org};
1533ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1534ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1535b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgvoid MarkCompactMarkingVisitor::ObjectStatsCountFixedArray(
15363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type,
1537304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    FixedArraySubInstanceType dictionary_type) {
1538304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  Heap* heap = fixed_array->map()->GetHeap();
1539304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  if (fixed_array->map() != heap->fixed_cow_array_map() &&
1540304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      fixed_array->map() != heap->fixed_double_array_map() &&
1541304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      fixed_array != heap->empty_fixed_array()) {
1542304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    if (fixed_array->IsDictionary()) {
15433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      heap->RecordFixedArraySubTypeStats(dictionary_type, fixed_array->Size());
1544304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    } else {
15453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      heap->RecordFixedArraySubTypeStats(fast_type, fixed_array->Size());
1546304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
1547304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
1548304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org}
1549304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
1550304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
1551b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgvoid MarkCompactMarkingVisitor::ObjectStatsVisitBase(
1552b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    MarkCompactMarkingVisitor::VisitorId id, Map* map, HeapObject* obj) {
1553753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  Heap* heap = map->GetHeap();
1554753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  int object_size = obj->Size();
1555e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org  heap->RecordObjectStats(map->instance_type(), object_size);
1556304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  non_count_table_.GetVisitorById(id)(map, obj);
1557304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  if (obj->IsJSObject()) {
1558304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    JSObject* object = JSObject::cast(obj);
15593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ObjectStatsCountFixedArray(object->elements(), DICTIONARY_ELEMENTS_SUB_TYPE,
1560304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org                               FAST_ELEMENTS_SUB_TYPE);
1561304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    ObjectStatsCountFixedArray(object->properties(),
1562304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org                               DICTIONARY_PROPERTIES_SUB_TYPE,
1563304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org                               FAST_PROPERTIES_SUB_TYPE);
1564304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
1565304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org}
1566304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
1567304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
15683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <MarkCompactMarkingVisitor::VisitorId id>
15693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid MarkCompactMarkingVisitor::ObjectStatsTracker<id>::Visit(Map* map,
15703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                              HeapObject* obj) {
1571304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  ObjectStatsVisitBase(id, map, obj);
1572753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org}
1573753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
1574753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
15753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <>
1576b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor::ObjectStatsTracker<
1577b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    MarkCompactMarkingVisitor::kVisitMap> {
1578304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org public:
1579304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  static inline void Visit(Map* map, HeapObject* obj) {
1580304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    Heap* heap = map->GetHeap();
1581304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    Map* map_obj = Map::cast(obj);
1582e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(map->instance_type() == MAP_TYPE);
1583304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    DescriptorArray* array = map_obj->instance_descriptors();
158406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    if (map_obj->owns_descriptors() &&
158506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org        array != heap->empty_descriptor_array()) {
1586304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      int fixed_array_size = array->Size();
1587e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org      heap->RecordFixedArraySubTypeStats(DESCRIPTOR_ARRAY_SUB_TYPE,
1588e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org                                         fixed_array_size);
1589304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
1590304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    if (map_obj->HasTransitionArray()) {
1591304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org      int fixed_array_size = map_obj->transitions()->Size();
1592e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org      heap->RecordFixedArraySubTypeStats(TRANSITION_ARRAY_SUB_TYPE,
1593e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org                                         fixed_array_size);
1594304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
1595ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    if (map_obj->has_code_cache()) {
1596ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      CodeCache* cache = CodeCache::cast(map_obj->code_cache());
1597e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org      heap->RecordFixedArraySubTypeStats(MAP_CODE_CACHE_SUB_TYPE,
1598e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org                                         cache->default_cache()->Size());
1599ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      if (!cache->normal_type_cache()->IsUndefined()) {
1600e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org        heap->RecordFixedArraySubTypeStats(
1601ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org            MAP_CODE_CACHE_SUB_TYPE,
1602ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org            FixedArray::cast(cache->normal_type_cache())->Size());
1603ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      }
1604304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
1605304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    ObjectStatsVisitBase(kVisitMap, map, obj);
1606304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
1607304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org};
1608304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
1609304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
16103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <>
1611b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor::ObjectStatsTracker<
1612b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    MarkCompactMarkingVisitor::kVisitCode> {
1613753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org public:
1614753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  static inline void Visit(Map* map, HeapObject* obj) {
1615753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    Heap* heap = map->GetHeap();
1616753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    int object_size = obj->Size();
1617e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(map->instance_type() == CODE_TYPE);
1618e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org    Code* code_obj = Code::cast(obj);
1619057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    heap->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetRawAge(),
1620e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org                                 object_size);
1621304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    ObjectStatsVisitBase(kVisitCode, map, obj);
1622304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
1623304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org};
1624304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
1625304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
16263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <>
1627b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor::ObjectStatsTracker<
1628b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    MarkCompactMarkingVisitor::kVisitSharedFunctionInfo> {
1629304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org public:
1630304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  static inline void Visit(Map* map, HeapObject* obj) {
1631304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    Heap* heap = map->GetHeap();
1632304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
1633304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    if (sfi->scope_info() != heap->empty_fixed_array()) {
1634e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org      heap->RecordFixedArraySubTypeStats(
16353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          SCOPE_INFO_SUB_TYPE, FixedArray::cast(sfi->scope_info())->Size());
1636304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
1637304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    ObjectStatsVisitBase(kVisitSharedFunctionInfo, map, obj);
1638304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  }
1639304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org};
1640304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
1641304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
16423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <>
1643b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgclass MarkCompactMarkingVisitor::ObjectStatsTracker<
1644b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    MarkCompactMarkingVisitor::kVisitFixedArray> {
1645304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org public:
1646304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  static inline void Visit(Map* map, HeapObject* obj) {
1647304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    Heap* heap = map->GetHeap();
1648304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    FixedArray* fixed_array = FixedArray::cast(obj);
16494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (fixed_array == heap->string_table()) {
16503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      heap->RecordFixedArraySubTypeStats(STRING_TABLE_SUB_TYPE,
16513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                         fixed_array->Size());
1652304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    }
1653304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org    ObjectStatsVisitBase(kVisitFixedArray, map, obj);
1654753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  }
1655753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org};
1656753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
1657753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
1658b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgvoid MarkCompactMarkingVisitor::Initialize() {
1659b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize();
1660753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
16613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  table_.Register(kVisitJSRegExp, &VisitRegExpAndFlushCode);
1662753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
1663753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (FLAG_track_gc_object_stats) {
1664753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    // Copy the visitor table to make call-through possible.
1665753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    non_count_table_.CopyFrom(&table_);
16663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define VISITOR_ID_COUNT_FUNCTION(id) \
16673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  table_.Register(kVisit##id, ObjectStatsTracker<kVisit##id>::Visit);
1668753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org    VISITOR_ID_LIST(VISITOR_ID_COUNT_FUNCTION)
1669753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org#undef VISITOR_ID_COUNT_FUNCTION
1670753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  }
1671753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org}
1672753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
1673753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org
1674b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.orgVisitorDispatchTable<MarkCompactMarkingVisitor::Callback>
1675b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    MarkCompactMarkingVisitor::non_count_table_;
1676ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1677ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
16780b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgclass CodeMarkingVisitor : public ThreadVisitor {
16790b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org public:
1680ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit CodeMarkingVisitor(MarkCompactCollector* collector)
1681ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : collector_(collector) {}
1682ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
168374f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
168464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    collector_->PrepareThreadForCodeFlushing(isolate, top);
16850b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  }
1686ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1687ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org private:
1688ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  MarkCompactCollector* collector_;
16890b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org};
16900b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
16910b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
16920b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgclass SharedFunctionInfoMarkingVisitor : public ObjectVisitor {
16930b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org public:
1694ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector)
1695ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : collector_(collector) {}
1696ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
16972ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  void VisitPointers(Object** start, Object** end) {
16982ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    for (Object** p = start; p < end; p++) VisitPointer(p);
16990b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  }
17000b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
17010b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  void VisitPointer(Object** slot) {
17020b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org    Object* obj = *slot;
1703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (obj->IsSharedFunctionInfo()) {
1704a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj);
1705c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      MarkBit shared_mark = Marking::MarkBitFrom(shared);
170664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      MarkBit code_mark = Marking::MarkBitFrom(shared->code());
170764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      collector_->MarkObject(shared->code(), code_mark);
1708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      collector_->MarkObject(shared, shared_mark);
17090b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org    }
17100b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  }
1711ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1712ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org private:
1713ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  MarkCompactCollector* collector_;
17140b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org};
17150b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
17160b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
171764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate,
171864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                                        ThreadLocalTop* top) {
171964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) {
172064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // Note: for the frame that has a pending lazy deoptimization
172164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // StackFrame::unchecked_code will return a non-optimized code object for
172264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // the outermost function and StackFrame::LookupCode will return
172364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // actual optimized code object.
172464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    StackFrame* frame = it.frame();
172564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    Code* code = frame->unchecked_code();
172664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MarkBit code_mark = Marking::MarkBitFrom(code);
172764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    MarkObject(code, code_mark);
172864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    if (frame->is_optimized()) {
1729c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org      MarkCompactMarkingVisitor::MarkInlinedFunctionsCode(heap(),
1730c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                                                          frame->LookupCode());
173164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    }
173264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
173364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
173464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
173564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
17360b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid MarkCompactCollector::PrepareForCodeFlushing() {
1737e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // Enable code flushing for non-incremental cycles.
1738e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (FLAG_flush_code && !FLAG_flush_code_incrementally) {
1739e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    EnableCodeFlushing(!was_marked_incrementally_);
1740b101611b084c6b9ec7f7e5f174d40183dd665f2cmstarzinger@chromium.org  }
1741b101611b084c6b9ec7f7e5f174d40183dd665f2cmstarzinger@chromium.org
1742e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  // If code flushing is disabled, there is no need to prepare for it.
1743e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  if (!is_code_flushing_enabled()) return;
17440b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
17455b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // Ensure that empty descriptor array is marked. Method MarkDescriptorArray
17465b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org  // relies on it being marked before any other descriptor array.
1747c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  HeapObject* descriptor_array = heap()->empty_descriptor_array();
1748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkBit descriptor_array_mark = Marking::MarkBitFrom(descriptor_array);
1749c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkObject(descriptor_array, descriptor_array_mark);
17505b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org
17510b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // Make sure we are not referencing the code from the stack.
1752e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(this == heap()->mark_compact_collector());
175364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  PrepareThreadForCodeFlushing(heap()->isolate(),
175464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                               heap()->isolate()->thread_local_top());
17550b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
17560b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // Iterate the archived stacks in all threads to check if
17570b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  // the code is referenced.
1758ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  CodeMarkingVisitor code_marking_visitor(this);
1759c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  heap()->isolate()->thread_manager()->IterateArchivedThreads(
1760ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      &code_marking_visitor);
17610b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
1762ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  SharedFunctionInfoMarkingVisitor visitor(this);
1763c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  heap()->isolate()->compilation_cache()->IterateFunctions(&visitor);
1764c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  heap()->isolate()->handle_scope_implementer()->Iterate(&visitor);
17650b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
1766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ProcessMarkingDeque();
17670b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org}
17680b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
17690b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
177031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Visitor class for marking heap roots.
177131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.agerclass RootMarkingVisitor : public ObjectVisitor {
177231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager public:
1773ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit RootMarkingVisitor(Heap* heap)
17743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      : collector_(heap->mark_compact_collector()) {}
1775ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
17763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  void VisitPointer(Object** p) { MarkObjectByPointer(p); }
177731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
17782ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  void VisitPointers(Object** start, Object** end) {
17792ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
178031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  }
178131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
1782895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  // Skip the weak next code link in a code object, which is visited in
1783895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org  // ProcessTopOptimizedFrame.
17843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  void VisitNextCodeLink(Object** p) {}
1785895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org
178631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager private:
178731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  void MarkObjectByPointer(Object** p) {
178831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    if (!(*p)->IsHeapObject()) return;
178931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
179031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    // Replace flat cons strings in place.
179131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    HeapObject* object = ShortCircuitConsString(p);
1792c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(object);
1793c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (mark_bit.Get()) return;
179431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
179531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    Map* map = object->map();
179631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    // Mark the object.
1797c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    collector_->SetMark(object, mark_bit);
1798ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
179931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    // Mark the map pointer and body, and push them on the marking stack.
1800c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit map_mark = Marking::MarkBitFrom(map);
1801c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    collector_->MarkObject(map, map_mark);
1802b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org    MarkCompactMarkingVisitor::IterateBody(map, object);
180331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
180431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    // Mark all the objects reachable from the map and body.  May leave
180531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager    // overflowed objects in the heap.
1806c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    collector_->EmptyMarkingDeque();
180731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  }
1808ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1809ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  MarkCompactCollector* collector_;
181031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager};
181131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
181231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
18134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org// Helper class for pruning the string table.
18143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <bool finalize_external_strings>
18154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgclass StringTableCleaner : public ObjectVisitor {
181643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
18173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  explicit StringTableCleaner(Heap* heap) : heap_(heap), pointers_removed_(0) {}
181813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
18192ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  virtual void VisitPointers(Object** start, Object** end) {
18202ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    // Visit all HeapObject pointers in [start, end).
18212ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    for (Object** p = start; p < end; p++) {
1822c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object* o = *p;
1823c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (o->IsHeapObject() &&
1824c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          !Marking::MarkBitFrom(HeapObject::cast(o)).Get()) {
1825113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org        if (finalize_external_strings) {
1826e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(o->IsExternalString());
1827c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org          heap_->FinalizeExternalString(String::cast(*p));
1828113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org        } else {
1829113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org          pointers_removed_++;
18306f10e41fef1524c70846d970268de222e41c594cager@chromium.org        }
1831c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        // Set the entry to the_hole_value (as deleted).
1832c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        *p = heap_->the_hole_value();
183343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
183443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
183543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
183643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
183743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int PointersRemoved() {
1838e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!finalize_external_strings);
183943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return pointers_removed_;
184043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1841e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
184243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
1843c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Heap* heap_;
184443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int pointers_removed_;
184543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
184643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
184743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1848113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.orgtypedef StringTableCleaner<false> InternalizedStringTableCleaner;
1849113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.orgtypedef StringTableCleaner<true> ExternalStringTableCleaner;
1850113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org
1851113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org
18524a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org// Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
18534a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org// are retained.
18544a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgclass MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
18554a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org public:
18564a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  virtual Object* RetainAs(Object* object) {
1857c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (Marking::MarkBitFrom(HeapObject::cast(object)).Get()) {
18584a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org      return object;
1859c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    } else if (object->IsAllocationSite() &&
1860c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org               !(AllocationSite::cast(object)->IsZombie())) {
1861c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org      // "dead" AllocationSites need to live long enough for a traversal of new
1862c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org      // space. These sites get a one-time reprieve.
1863c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org      AllocationSite* site = AllocationSite::cast(object);
1864c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org      site->MarkZombie();
1865c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org      site->GetHeap()->mark_compact_collector()->MarkAllocationSite(site);
1866c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org      return object;
18674a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org    } else {
18684a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org      return NULL;
18694a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org    }
18704a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  }
18714a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org};
18724a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
18734a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
1874c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Fill the marking stack with overflowed objects returned by the given
1875c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// iterator.  Stop when the marking stack is filled or the end of the space
1876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// is reached, whichever comes first.
18773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <class T>
1878c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic void DiscoverGreyObjectsWithIterator(Heap* heap,
1879c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                            MarkingDeque* marking_deque,
1880c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                            T* it) {
1881c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The caller should ensure that the marking stack is initially not full,
1882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // so that we don't waste effort pointlessly scanning for objects.
1883e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!marking_deque->IsFull());
188443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Map* filler_map = heap->one_pointer_filler_map();
18863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) {
1887c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit markbit = Marking::MarkBitFrom(object);
1888c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if ((object->map() != filler_map) && Marking::IsGrey(markbit)) {
1889c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Marking::GreyToBlack(markbit);
18902efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size());
1891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      marking_deque->PushBlack(object);
1892c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (marking_deque->IsFull()) return;
189343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
189443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
1895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
189743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts);
189943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
190043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1901bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgstatic void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque,
1902bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                      MemoryChunk* p) {
1903e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!marking_deque->IsFull());
1904e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
1905e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
1906e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0);
1907e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
19085ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
190910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) {
191010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    Address cell_base = it.CurrentCellBase();
191110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    MarkBit::CellType* cell = it.CurrentCell();
19125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
191310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    const MarkBit::CellType current_cell = *cell;
1914c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (current_cell == 0) continue;
1915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
191610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    MarkBit::CellType grey_objects;
191710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    if (it.HasNext()) {
19183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      const MarkBit::CellType next_cell = *(cell + 1);
19193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      grey_objects = current_cell & ((current_cell >> 1) |
19203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                     (next_cell << (Bitmap::kBitsPerCell - 1)));
192110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    } else {
192210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      grey_objects = current_cell & (current_cell >> 1);
192310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    }
1924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int offset = 0;
1926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    while (grey_objects != 0) {
1927e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects);
1928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      grey_objects >>= trailing_zeros;
1929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      offset += trailing_zeros;
193010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      MarkBit markbit(cell, 1 << offset, false);
1931e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(Marking::IsGrey(markbit));
1932c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Marking::GreyToBlack(markbit);
1933c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Address addr = cell_base + offset * kPointerSize;
1934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HeapObject* object = HeapObject::FromAddress(addr);
19352efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size());
1936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      marking_deque->PushBlack(object);
1937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (marking_deque->IsFull()) return;
1938c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      offset += 2;
1939c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      grey_objects >>= 2;
1940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
1941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    grey_objects >>= (Bitmap::kBitsPerCell - 1);
1943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
1945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1946c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1947975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgint MarkCompactCollector::DiscoverAndEvacuateBlackObjectsOnPage(
19483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    NewSpace* new_space, NewSpacePage* p) {
1949e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
1950e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
1951e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0);
1952e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
1953169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1954169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  MarkBit::CellType* cells = p->markbits()->cells();
1955169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  int survivors_size = 0;
1956169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
195710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) {
195810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    Address cell_base = it.CurrentCellBase();
195910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    MarkBit::CellType* cell = it.CurrentCell();
196010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
196110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    MarkBit::CellType current_cell = *cell;
1962169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    if (current_cell == 0) continue;
1963169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1964169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    int offset = 0;
1965169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    while (current_cell != 0) {
1966e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      int trailing_zeros = base::bits::CountTrailingZeros32(current_cell);
1967169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      current_cell >>= trailing_zeros;
1968169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      offset += trailing_zeros;
1969169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      Address address = cell_base + offset * kPointerSize;
1970169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      HeapObject* object = HeapObject::FromAddress(address);
1971169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1972169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      int size = object->Size();
1973169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      survivors_size += size;
1974169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1975bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT);
1976d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1977169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      offset++;
1978169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      current_cell >>= 1;
1979975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
1980975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org      // TODO(hpayer): Refactor EvacuateObject and call this function instead.
1981975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org      if (heap()->ShouldBePromoted(object->address(), size) &&
1982975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org          TryPromoteObject(object, size)) {
1983169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        continue;
1984169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      }
1985169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
1986a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      AllocationResult allocation = new_space->AllocateRaw(size);
1987a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if (allocation.IsRetry()) {
1988169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        if (!new_space->AddFreshPage()) {
1989169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org          // Shouldn't happen. We are sweeping linearly, and to-space
1990169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org          // has the same number of pages as from-space, so there is
1991169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org          // always room.
1992169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org          UNREACHABLE();
1993169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        }
1994169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        allocation = new_space->AllocateRaw(size);
1995e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(!allocation.IsRetry());
1996169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      }
1997a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      Object* target = allocation.ToObjectChecked();
1998169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
19993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      MigrateObject(HeapObject::cast(target), object, size, NEW_SPACE);
20006a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org      heap()->IncrementSemiSpaceCopiedObjectSize(size);
2001169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    }
200210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    *cells = 0;
2003169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
2004169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  return survivors_size;
2005169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
2006169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
2007169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
20083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic void DiscoverGreyObjectsInSpace(Heap* heap, MarkingDeque* marking_deque,
2009c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                       PagedSpace* space) {
20104bac458fb0ebad9b4b21cf110fad3a713115f9b1jochen@chromium.org  PageIterator it(space);
20114bac458fb0ebad9b4b21cf110fad3a713115f9b1jochen@chromium.org  while (it.has_next()) {
20124bac458fb0ebad9b4b21cf110fad3a713115f9b1jochen@chromium.org    Page* p = it.next();
20134bac458fb0ebad9b4b21cf110fad3a713115f9b1jochen@chromium.org    DiscoverGreyObjectsOnPage(marking_deque, p);
20144bac458fb0ebad9b4b21cf110fad3a713115f9b1jochen@chromium.org    if (marking_deque->IsFull()) return;
2015c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
2016c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
2017c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2018c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2019bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgstatic void DiscoverGreyObjectsInNewSpace(Heap* heap,
2020bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                          MarkingDeque* marking_deque) {
2021bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  NewSpace* space = heap->new_space();
2022bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  NewSpacePageIterator it(space->bottom(), space->top());
2023bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  while (it.has_next()) {
2024bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    NewSpacePage* page = it.next();
2025bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    DiscoverGreyObjectsOnPage(marking_deque, page);
2026bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    if (marking_deque->IsFull()) return;
2027bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  }
2028bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
2029bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
2030bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
2031c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
2032c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Object* o = *p;
2033c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (!o->IsHeapObject()) return false;
2034c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  HeapObject* heap_object = HeapObject::cast(o);
2035c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkBit mark = Marking::MarkBitFrom(heap_object);
2036c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return !mark.Get();
2037c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
2038c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2039c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
204049a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgbool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap,
204149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                                        Object** p) {
204249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  Object* o = *p;
2043e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(o->IsHeapObject());
204449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  HeapObject* heap_object = HeapObject::cast(o);
204549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  MarkBit mark = Marking::MarkBitFrom(heap_object);
204649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  return !mark.Get();
204749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
204849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
204949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
20501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) {
20514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  StringTable* string_table = heap()->string_table();
20524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Mark the string table itself.
20534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  MarkBit string_table_mark = Marking::MarkBitFrom(string_table);
2054b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  if (!string_table_mark.Get()) {
2055b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org    // String table could have already been marked by visiting the handles list.
2056b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org    SetMark(string_table, string_table_mark);
2057b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  }
2058c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Explicitly mark the prefix.
20591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  string_table->IteratePrefix(visitor);
2060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ProcessMarkingDeque();
2061c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
2062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2064c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.orgvoid MarkCompactCollector::MarkAllocationSite(AllocationSite* site) {
2065c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org  MarkBit mark_bit = Marking::MarkBitFrom(site);
2066c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org  SetMark(site, mark_bit);
2067c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org}
2068c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
2069c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
2070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
2071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Mark the heap roots including global variables, stack variables,
2072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // etc., and all objects reachable from them.
2073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
2074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
20754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Handle the string table specially.
20761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  MarkStringTable(visitor);
2077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
207825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  MarkWeakObjectToCodeTable();
207925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
2080c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // There may be overflowed objects in the heap.  Visit them now.
2081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (marking_deque_.overflowed()) {
2082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    RefillMarkingDeque();
2083c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    EmptyMarkingDeque();
2084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
20857276f14ca716596e0a0d17539516370c1f453847kasper.lund}
20867276f14ca716596e0a0d17539516370c1f453847kasper.lund
20877276f14ca716596e0a0d17539516370c1f453847kasper.lund
2088badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MarkCompactCollector::MarkImplicitRefGroups() {
2089ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  List<ImplicitRefGroup*>* ref_groups =
2090876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      isolate()->global_handles()->implicit_ref_groups();
2091badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
209244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  int last = 0;
2093badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  for (int i = 0; i < ref_groups->length(); i++) {
2094badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    ImplicitRefGroup* entry = ref_groups->at(i);
2095e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(entry != NULL);
2096badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
2097ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if (!IsMarked(*entry->parent)) {
209844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      (*ref_groups)[last++] = entry;
209944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      continue;
210044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    }
2101badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
2102ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Object*** children = entry->children;
210344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    // A parent object is marked, so mark all child heap objects.
2104ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    for (size_t j = 0; j < entry->length; ++j) {
2105badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      if ((*children[j])->IsHeapObject()) {
2106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        HeapObject* child = HeapObject::cast(*children[j]);
2107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        MarkBit mark = Marking::MarkBitFrom(child);
2108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        MarkObject(child, mark);
2109badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org      }
2110badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    }
2111badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
211244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    // Once the entire group has been marked, dispose it because it's
211344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    // not needed anymore.
2114ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    delete entry;
2115badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  }
211644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  ref_groups->Rewind(last);
2117badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org}
2118badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
2119badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
212025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.orgvoid MarkCompactCollector::MarkWeakObjectToCodeTable() {
212125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  HeapObject* weak_object_to_code_table =
212225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      HeapObject::cast(heap()->weak_object_to_code_table());
212325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  if (!IsMarked(weak_object_to_code_table)) {
212425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    MarkBit mark = Marking::MarkBitFrom(weak_object_to_code_table);
212525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    SetMark(weak_object_to_code_table, mark);
212625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
212725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org}
212825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
212925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
213031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Mark all objects reachable from the objects on the marking stack.
213131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Before: the marking stack contains zero or more heap object pointers.
213231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// After: the marking stack is empty, and all objects reachable from the
213331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// marking stack have been marked, or are overflowed in the heap.
2134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EmptyMarkingDeque() {
2135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (!marking_deque_.IsEmpty()) {
2136d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    HeapObject* object = marking_deque_.Pop();
2137e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(object->IsHeapObject());
2138e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(heap()->Contains(object));
2139e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
21407c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
2141d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    Map* map = object->map();
2142d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    MarkBit map_mark = Marking::MarkBitFrom(map);
2143d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    MarkObject(map, map_mark);
2144ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
2145d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    MarkCompactMarkingVisitor::IterateBody(map, object);
214631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  }
214731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager}
214831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
214943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
215031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Sweep the heap for overflowed objects, clear their overflow bits, and
215131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// push them on the marking stack.  Stop early if the marking stack fills
215231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// before sweeping completes.  If sweeping completes, there are no remaining
215331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// overflowed objects in the heap so the overflow flag on the markings stack
215431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// is cleared.
2155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::RefillMarkingDeque() {
2156e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(marking_deque_.overflowed());
215743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2158bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_);
2159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (marking_deque_.IsFull()) return;
216043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DiscoverGreyObjectsInSpace(heap(), &marking_deque_,
2162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                             heap()->old_pointer_space());
2163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (marking_deque_.IsFull()) return;
21649258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
21653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_data_space());
2166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (marking_deque_.IsFull()) return;
216743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space());
2169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (marking_deque_.IsFull()) return;
217043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space());
2172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (marking_deque_.IsFull()) return;
217343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space());
2175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (marking_deque_.IsFull()) return;
2176defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
21773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DiscoverGreyObjectsInSpace(heap(), &marking_deque_,
217841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org                             heap()->property_cell_space());
217941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (marking_deque_.IsFull()) return;
218041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
2181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  LargeObjectIterator lo_it(heap()->lo_space());
21823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it);
2183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (marking_deque_.IsFull()) return;
218431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
2185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  marking_deque_.ClearOverflowed();
218631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager}
218731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
218831e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
218931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// Mark all objects reachable (transitively) from objects on the marking
219031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// stack.  Before: the marking stack contains zero or more heap object
219131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// pointers.  After: the marking stack is empty and there are no overflowed
219231e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager// objects in the heap.
2193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::ProcessMarkingDeque() {
2194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  EmptyMarkingDeque();
2195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (marking_deque_.overflowed()) {
2196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    RefillMarkingDeque();
2197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    EmptyMarkingDeque();
219843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
21997276f14ca716596e0a0d17539516370c1f453847kasper.lund}
22007276f14ca716596e0a0d17539516370c1f453847kasper.lund
22017276f14ca716596e0a0d17539516370c1f453847kasper.lund
2202d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org// Mark all objects reachable (transitively) from objects on the marking
2203d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org// stack including references only considered in the atomic marking pause.
2204d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgvoid MarkCompactCollector::ProcessEphemeralMarking(ObjectVisitor* visitor) {
22057276f14ca716596e0a0d17539516370c1f453847kasper.lund  bool work_to_do = true;
2206e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(marking_deque_.IsEmpty());
22077276f14ca716596e0a0d17539516370c1f453847kasper.lund  while (work_to_do) {
2208876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    isolate()->global_handles()->IterateObjectGroups(
220949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org        visitor, &IsUnmarkedHeapObjectWithHeap);
2210badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    MarkImplicitRefGroups();
2211ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    ProcessWeakCollections();
2212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    work_to_do = !marking_deque_.IsEmpty();
2213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ProcessMarkingDeque();
22147276f14ca716596e0a0d17539516370c1f453847kasper.lund  }
22157276f14ca716596e0a0d17539516370c1f453847kasper.lund}
22167276f14ca716596e0a0d17539516370c1f453847kasper.lund
22177276f14ca716596e0a0d17539516370c1f453847kasper.lund
2218c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) {
2219c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  for (StackFrameIterator it(isolate(), isolate()->thread_local_top());
2220c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org       !it.done(); it.Advance()) {
2221c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    if (it.frame()->type() == StackFrame::JAVA_SCRIPT) {
2222c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      return;
2223c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    }
2224c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    if (it.frame()->type() == StackFrame::OPTIMIZED) {
2225c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      Code* code = it.frame()->LookupCode();
2226c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      if (!code->CanDeoptAt(it.frame()->pc())) {
2227c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org        code->CodeIterateBody(visitor);
2228c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      }
2229c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      ProcessMarkingDeque();
2230c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      return;
2231c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    }
2232c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  }
2233c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org}
2234c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
2235c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
22367276f14ca716596e0a0d17539516370c1f453847kasper.lundvoid MarkCompactCollector::MarkLiveObjects() {
2237474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK);
22385c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  double start_time = 0.0;
22395c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  if (FLAG_print_cumulative_gc_stat) {
22405c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    start_time = base::OS::TimeCurrentMillis();
22415c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  }
22425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // The recursive GC marker detects when it is nearing stack overflow,
22435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // and switches to a different marking system.  JS interrupts interfere
22445f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // with the C stack limit check.
2245876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  PostponeInterruptsScope postpone(isolate());
22465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
2247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool incremental_marking_overflowed = false;
2248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  IncrementalMarking* incremental_marking = heap_->incremental_marking();
2249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (was_marked_incrementally_) {
2250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Finalize the incremental marking and check whether we had an overflow.
2251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Both markers use grey color to mark overflowed objects so
2252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // non-incremental marker can deal with them as if overflow
2253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // occured during normal marking.
2254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // But incremental marker uses a separate marking deque
225556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org    // so we have to explicitly copy its overflow state.
2256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    incremental_marking->Finalize();
2257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    incremental_marking_overflowed =
2258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        incremental_marking->marking_deque()->overflowed();
2259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    incremental_marking->marking_deque()->ClearOverflowed();
2260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
2261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Abort any pending incremental activities e.g. incremental sweeping.
2262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    incremental_marking->Abort();
2263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
2264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
22657276f14ca716596e0a0d17539516370c1f453847kasper.lund#ifdef DEBUG
2266e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(state_ == PREPARE_GC);
22677276f14ca716596e0a0d17539516370c1f453847kasper.lund  state_ = MARK_LIVE_OBJECTS;
22687276f14ca716596e0a0d17539516370c1f453847kasper.lund#endif
2269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The to space contains live objects, a page in from space is used as a
2270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // marking stack.
2271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address marking_deque_start = heap()->new_space()->FromSpacePageLow();
2272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address marking_deque_end = heap()->new_space()->FromSpacePageHigh();
2273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (FLAG_force_marking_deque_overflows) {
2274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    marking_deque_end = marking_deque_start + 64 * kPointerSize;
2275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
22763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  marking_deque_.Initialize(marking_deque_start, marking_deque_end);
2277e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!marking_deque_.overflowed());
22787276f14ca716596e0a0d17539516370c1f453847kasper.lund
2279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (incremental_marking_overflowed) {
2280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // There are overflowed objects left in the heap after incremental marking.
2281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    marking_deque_.SetOverflowed();
2282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
228343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22840b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  PrepareForCodeFlushing();
22850b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
228664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (was_marked_incrementally_) {
228764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // There is no write barrier on cells so we have to scan them now at the end
228864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // of the incremental marking.
228964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    {
229064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      HeapObjectIterator cell_iterator(heap()->cell_space());
229164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      HeapObject* cell;
229264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      while ((cell = cell_iterator.Next()) != NULL) {
2293e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(cell->IsCell());
229441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        if (IsMarked(cell)) {
229541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          int offset = Cell::kValueOffset;
229641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          MarkCompactMarkingVisitor::VisitPointer(
22973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              heap(), reinterpret_cast<Object**>(cell->address() + offset));
229841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        }
229941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      }
230041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
230141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    {
230241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      HeapObjectIterator js_global_property_cell_iterator(
230341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org          heap()->property_cell_space());
230441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      HeapObject* cell;
230541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      while ((cell = js_global_property_cell_iterator.Next()) != NULL) {
2306e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(cell->IsPropertyCell());
230764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        if (IsMarked(cell)) {
23081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org          MarkCompactMarkingVisitor::VisitPropertyCell(cell->map(), cell);
230964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        }
231064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      }
231164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    }
231264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
231364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
2314c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  RootMarkingVisitor root_visitor(heap());
23155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org  MarkRoots(&root_visitor);
23167276f14ca716596e0a0d17539516370c1f453847kasper.lund
2317c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  ProcessTopOptimizedFrame(&root_visitor);
2318c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org
23199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // The objects reachable from the roots are marked, yet unreachable
2320badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // objects are unmarked.  Mark objects reachable due to host
2321d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // application specific logic or through Harmony weak maps.
2322d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ProcessEphemeralMarking(&root_visitor);
23237276f14ca716596e0a0d17539516370c1f453847kasper.lund
2324d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // The objects reachable from the roots, weak maps or object groups
2325d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // are marked, yet unreachable objects are unmarked.  Mark objects
2326d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // reachable only from weak global handles.
23277276f14ca716596e0a0d17539516370c1f453847kasper.lund  //
23289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // First we identify nonlive weak handles and mark them as pending
23299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // destruction.
2330c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  heap()->isolate()->global_handles()->IdentifyWeakHandles(
2331ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      &IsUnmarkedHeapObject);
23329085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Then we mark the objects and process the transitive closure.
2333c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor);
2334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (marking_deque_.overflowed()) {
2335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    RefillMarkingDeque();
2336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    EmptyMarkingDeque();
233731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  }
23387276f14ca716596e0a0d17539516370c1f453847kasper.lund
2339d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // Repeat host application specific and Harmony weak maps marking to
2340d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  // mark unmarked objects reachable from the weak roots.
2341d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ProcessEphemeralMarking(&root_visitor);
23427276f14ca716596e0a0d17539516370c1f453847kasper.lund
2343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  AfterMarking();
23445c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org
23455c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  if (FLAG_print_cumulative_gc_stat) {
23465c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    heap_->tracer()->AddMarkingTime(base::OS::TimeCurrentMillis() - start_time);
23475c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  }
2348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
2349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::AfterMarking() {
23524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Object literal map caches reference strings (cache keys) and maps
23534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // (cache values). At this point still useful maps have already been
23544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  // marked. Mark the keys for the alive values before we process the
23554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // string table.
23564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  ProcessMapCaches();
23574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
23584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Prune the string table removing all strings only pointed to by the
23594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // string table.  Cannot use string_table() here because the string
23607276f14ca716596e0a0d17539516370c1f453847kasper.lund  // table is marked.
23614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  StringTable* string_table = heap()->string_table();
2362113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  InternalizedStringTableCleaner internalized_visitor(heap());
2363113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  string_table->IterateElements(&internalized_visitor);
2364113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  string_table->ElementsRemoved(internalized_visitor.PointersRemoved());
2365113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org
2366113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  ExternalStringTableCleaner external_visitor(heap());
2367113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org  heap()->external_string_table_.Iterate(&external_visitor);
2368c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  heap()->external_string_table_.CleanUp();
236943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23704a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  // Process the weak references.
23714a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  MarkCompactWeakObjectRetainer mark_compact_object_retainer;
2372c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  heap()->ProcessWeakReferences(&mark_compact_object_retainer);
23734a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
237443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Remove object groups after marking phase.
2375c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  heap()->isolate()->global_handles()->RemoveObjectGroups();
2376c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  heap()->isolate()->global_handles()->RemoveImplicitRefGroups();
2377a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2378a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Flush code from collected candidates.
2379ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (is_code_flushing_enabled()) {
2380ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    code_flusher_->ProcessCandidates();
2381e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    // If incremental marker does not support code flushing, we need to
2382e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    // disable it before incremental marking steps for next cycle.
2383e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    if (FLAG_flush_code && !FLAG_flush_code_incrementally) {
2384e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org      EnableCodeFlushing(false);
2385e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    }
2386ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
23879ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
238828583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  if (FLAG_track_gc_object_stats) {
238928583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org    heap()->CheckpointObjectStats();
239028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  }
239143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
239243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
239343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
23944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgvoid MarkCompactCollector::ProcessMapCaches() {
23953c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  Object* raw_context = heap()->native_contexts_list();
23964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  while (raw_context != heap()->undefined_value()) {
23974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    Context* context = reinterpret_cast<Context*>(raw_context);
2398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (IsMarked(context)) {
23994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      HeapObject* raw_map_cache =
24004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          HeapObject::cast(context->get(Context::MAP_CACHE_INDEX));
24014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      // A map cache may be reachable from the stack. In this case
24024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      // it's already transitively marked and it's too late to clean
24034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      // up its parts.
2404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (!IsMarked(raw_map_cache) &&
24054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          raw_map_cache != heap()->undefined_value()) {
24064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        MapCache* map_cache = reinterpret_cast<MapCache*>(raw_map_cache);
24074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        int existing_elements = map_cache->NumberOfElements();
24084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        int used_elements = 0;
24093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        for (int i = MapCache::kElementsStartIndex; i < map_cache->length();
24104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org             i += MapCache::kEntrySize) {
24114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          Object* raw_key = map_cache->get(i);
24124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          if (raw_key == heap()->undefined_value() ||
24133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org              raw_key == heap()->the_hole_value())
24143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            continue;
24154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          STATIC_ASSERT(MapCache::kEntrySize == 2);
24164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          Object* raw_map = map_cache->get(i + 1);
2417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          if (raw_map->IsHeapObject() && IsMarked(raw_map)) {
24184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org            ++used_elements;
24194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          } else {
24204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org            // Delete useless entries with unmarked maps.
2421e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            DCHECK(raw_map->IsMap());
2422c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            map_cache->set_the_hole(i);
2423c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            map_cache->set_the_hole(i + 1);
24244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          }
24254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        }
24264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        if (used_elements == 0) {
24274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          context->set(Context::MAP_CACHE_INDEX, heap()->undefined_value());
24284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        } else {
24294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          // Note: we don't actually shrink the cache here to avoid
24304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          // extra complexity during GC. We rely on subsequent cache
24314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          // usages (EnsureCapacity) to do this.
24324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org          map_cache->ElementsRemoved(existing_elements - used_elements);
2433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          MarkBit map_cache_markbit = Marking::MarkBitFrom(map_cache);
2434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          MarkObject(map_cache, map_cache_markbit);
24354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org        }
24364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org      }
24374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    }
24384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    // Move to next element in the list.
24394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    raw_context = context->get(Context::NEXT_CONTEXT_LINK);
24404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
2441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ProcessMarkingDeque();
24424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}
24434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
24444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
2445003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgvoid MarkCompactCollector::ClearNonLiveReferences() {
24469bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  // Iterate over the map space, setting map transitions that go from
2447212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  // a marked map to an unmarked map to null transitions.  This action
2448212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  // is carried out only on maps of JSObjects and related subtypes.
24491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HeapObjectIterator map_iterator(heap()->map_space());
24503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (HeapObject* obj = map_iterator.Next(); obj != NULL;
24511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org       obj = map_iterator.Next()) {
24521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Map* map = Map::cast(obj);
24539bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org
2454003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    if (!map->CanTransition()) continue;
24554a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
24561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    MarkBit map_mark = Marking::MarkBitFrom(map);
2457659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    ClearNonLivePrototypeTransitions(map);
2458659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    ClearNonLiveMapTransitions(map, map_mark);
2459003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2460003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    if (map_mark.Get()) {
24611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ClearNonLiveDependentCode(map->dependent_code());
2462003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    } else {
24632ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      ClearDependentCode(map->dependent_code());
246425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
2465003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
2466659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
24671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
24681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Iterate over property cell space, removing dependent code that is not
24691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // otherwise kept alive by strong references.
24701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  HeapObjectIterator cell_iterator(heap_->property_cell_space());
24713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (HeapObject* cell = cell_iterator.Next(); cell != NULL;
24721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org       cell = cell_iterator.Next()) {
24731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (IsMarked(cell)) {
24741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ClearNonLiveDependentCode(PropertyCell::cast(cell)->dependent_code());
24751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
24761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
247725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org
2478af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // Iterate over allocation sites, removing dependent code that is not
2479af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // otherwise kept alive by strong references.
2480af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  Object* undefined = heap()->undefined_value();
24813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (Object* site = heap()->allocation_sites_list(); site != undefined;
2482af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org       site = AllocationSite::cast(site)->weak_next()) {
2483af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    if (IsMarked(site)) {
2484af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org      ClearNonLiveDependentCode(AllocationSite::cast(site)->dependent_code());
2485af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    }
2486af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
2487af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
248825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  if (heap_->weak_object_to_code_table()->IsHashTable()) {
248925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    WeakHashTable* table =
249025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        WeakHashTable::cast(heap_->weak_object_to_code_table());
249125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    uint32_t capacity = table->Capacity();
249225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    for (uint32_t i = 0; i < capacity; i++) {
249325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      uint32_t key_index = table->EntryToIndex(i);
249425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      Object* key = table->get(key_index);
249525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      if (!table->IsKey(key)) continue;
249625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      uint32_t value_index = table->EntryToValueIndex(i);
249725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      Object* value = table->get(value_index);
249826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      if (key->IsCell() && !IsMarked(key)) {
249926ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org        Cell* cell = Cell::cast(key);
250026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org        Object* object = cell->value();
250126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org        if (IsMarked(object)) {
250226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org          MarkBit mark = Marking::MarkBitFrom(cell);
250326ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org          SetMark(cell, mark);
250426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org          Object** value_slot = HeapObject::RawField(cell, Cell::kValueOffset);
250526ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org          RecordSlot(value_slot, value_slot, *value_slot);
250626ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org        }
250726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org      }
250825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      if (IsMarked(key)) {
250925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        if (!IsMarked(value)) {
251025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org          HeapObject* obj = HeapObject::cast(value);
251125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org          MarkBit mark = Marking::MarkBitFrom(obj);
251225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org          SetMark(obj, mark);
251325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        }
251425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        ClearNonLiveDependentCode(DependentCode::cast(value));
251525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      } else {
25162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        ClearDependentCode(DependentCode::cast(value));
251725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        table->set(key_index, heap_->the_hole_value());
251825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        table->set(value_index, heap_->the_hole_value());
2519aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org        table->ElementRemoved();
252025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org      }
252125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    }
252225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
2523659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
2524659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2525659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2526659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgvoid MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) {
2527659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int number_of_transitions = map->NumberOfProtoTransitions();
252881cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org  FixedArray* prototype_transitions = map->GetPrototypeTransitions();
2529659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2530659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int new_number_of_transitions = 0;
2531659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  const int header = Map::kProtoTransitionHeaderSize;
2532659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  const int proto_offset = header + Map::kProtoTransitionPrototypeOffset;
2533659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  const int map_offset = header + Map::kProtoTransitionMapOffset;
2534659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  const int step = Map::kProtoTransitionElementsPerEntry;
2535659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  for (int i = 0; i < number_of_transitions; i++) {
2536659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Object* prototype = prototype_transitions->get(proto_offset + i * step);
2537659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    Object* cached_map = prototype_transitions->get(map_offset + i * step);
2538659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    if (IsMarked(prototype) && IsMarked(cached_map)) {
2539e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!prototype->IsUndefined());
2540659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      int proto_index = proto_offset + new_number_of_transitions * step;
2541659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      int map_index = map_offset + new_number_of_transitions * step;
2542659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      if (new_number_of_transitions != i) {
25433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        prototype_transitions->set(proto_index, prototype,
25443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   UPDATE_WRITE_BARRIER);
25453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        prototype_transitions->set(map_index, cached_map, SKIP_WRITE_BARRIER);
25463847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      }
25474954674151afa960af66efb4831df06bde727333yangguo@chromium.org      Object** slot = prototype_transitions->RawFieldOfElementAt(proto_index);
2548659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      RecordSlot(slot, slot, prototype);
2549659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      new_number_of_transitions++;
25502efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    }
2551659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
25523847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
2553659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  if (new_number_of_transitions != number_of_transitions) {
2554659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    map->SetNumberOfProtoTransitions(new_number_of_transitions);
2555659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
25563847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
2557659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  // Fill slots that became free with undefined value.
2558659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  for (int i = new_number_of_transitions * step;
25593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org       i < number_of_transitions * step; i++) {
25601f410f9a9c4fbd4270749af64b477df87b753158mstarzinger@chromium.org    prototype_transitions->set_undefined(header + i);
2561659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  }
2562659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org}
25632efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org
2564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2565659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgvoid MarkCompactCollector::ClearNonLiveMapTransitions(Map* map,
2566659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org                                                      MarkBit map_mark) {
2567212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  Object* potential_parent = map->GetBackPointer();
2568212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  if (!potential_parent->IsMap()) return;
2569212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  Map* parent = Map::cast(potential_parent);
2570659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org
2571212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  // Follow back pointer, check whether we are dealing with a map transition
2572212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  // from a live map to a dead path and in case clear transitions of parent.
2573659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  bool current_is_alive = map_mark.Get();
2574212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  bool parent_is_alive = Marking::MarkBitFrom(parent).Get();
2575212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  if (!current_is_alive && parent_is_alive) {
25763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    ClearMapTransitions(parent);
25779bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org  }
25789bbf968a649030335309265ba2c98fcc36aeb762kasperl@chromium.org}
257943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
25807c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
25813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// Clear a possible back pointer in case the transition leads to a dead map.
25823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org// Return true in case a back pointer has been cleared and false otherwise.
25833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgbool MarkCompactCollector::ClearMapBackPointer(Map* target) {
25843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (Marking::MarkBitFrom(target).Get()) return false;
25853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER);
25863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  return true;
25873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
25883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
25893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
25903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid MarkCompactCollector::ClearMapTransitions(Map* map) {
25913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // If there are no transitions to be cleared, return.
25923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // TODO(verwaest) Should be an assert, otherwise back pointers are not
25933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // properly cleared.
25943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (!map->HasTransitionArray()) return;
25953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
25963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  TransitionArray* t = map->transitions();
25973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
25983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int transition_index = 0;
25993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DescriptorArray* descriptors = map->instance_descriptors();
26013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  bool descriptors_owner_died = false;
26023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Compact all live descriptors to the left.
26043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (int i = 0; i < t->number_of_transitions(); ++i) {
26053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Map* target = t->GetTarget(i);
26063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (ClearMapBackPointer(target)) {
26073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      if (target->instance_descriptors() == descriptors) {
26083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        descriptors_owner_died = true;
26093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      }
26103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    } else {
26113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      if (i != transition_index) {
26123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        Name* key = t->GetKey(i);
26133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        t->SetKey(transition_index, key);
26143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        Object** key_slot = t->GetKeySlot(transition_index);
26153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        RecordSlot(key_slot, key_slot, key);
26163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        // Target slots do not need to be recorded since maps are not compacted.
26173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        t->SetTarget(transition_index, t->GetTarget(i));
26183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      }
26193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      transition_index++;
26203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    }
26213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
26223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // If there are no transitions to be cleared, return.
26243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // TODO(verwaest) Should be an assert, otherwise back pointers are not
26253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // properly cleared.
26263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (transition_index == t->number_of_transitions()) return;
26273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int number_of_own_descriptors = map->NumberOfOwnDescriptors();
26293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (descriptors_owner_died) {
26313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    if (number_of_own_descriptors > 0) {
26323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      TrimDescriptorArray(map, descriptors, number_of_own_descriptors);
26333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
26343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      map->set_owns_descriptors(true);
26353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    } else {
26363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      DCHECK(descriptors == heap_->empty_descriptor_array());
26373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    }
26383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
26393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // Note that we never eliminate a transition array, though we might right-trim
26413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // such that number_of_transitions() == 0. If this assumption changes,
26423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // TransitionArray::CopyInsert() will need to deal with the case that a
26433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  // transition array disappeared during GC.
26443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int trim = t->number_of_transitions() - transition_index;
26453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (trim > 0) {
26463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    heap_->RightTrimFixedArray<Heap::FROM_GC>(
26473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        t, t->IsSimpleTransition() ? trim
26483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                   : trim * TransitionArray::kTransitionSize);
26493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
26503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  DCHECK(map->HasTransitionArray());
26513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
26523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid MarkCompactCollector::TrimDescriptorArray(Map* map,
26553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                               DescriptorArray* descriptors,
26563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                               int number_of_own_descriptors) {
26573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int number_of_descriptors = descriptors->number_of_descriptors_storage();
26583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int to_trim = number_of_descriptors - number_of_own_descriptors;
26593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (to_trim == 0) return;
26603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  heap_->RightTrimFixedArray<Heap::FROM_GC>(
26623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      descriptors, to_trim * DescriptorArray::kDescriptorSize);
26633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
26643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (descriptors->HasEnumCache()) TrimEnumCache(map, descriptors);
26663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  descriptors->Sort();
26673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
26683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid MarkCompactCollector::TrimEnumCache(Map* map,
26713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                         DescriptorArray* descriptors) {
26723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int live_enum = map->EnumLength();
26733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (live_enum == kInvalidEnumCacheSentinel) {
26743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
26753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
26763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (live_enum == 0) return descriptors->ClearEnumCache();
26773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  FixedArray* enum_cache = descriptors->GetEnumCache();
26793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  int to_trim = enum_cache->length() - live_enum;
26813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (to_trim <= 0) return;
26823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  heap_->RightTrimFixedArray<Heap::FROM_GC>(descriptors->GetEnumCache(),
26833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                            to_trim);
26843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (!descriptors->HasEnumIndicesCache()) return;
26863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache();
26873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  heap_->RightTrimFixedArray<Heap::FROM_GC>(enum_indices_cache, to_trim);
26883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
26893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
26912ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid MarkCompactCollector::ClearDependentICList(Object* head) {
26922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Object* current = head;
26932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Object* undefined = heap()->undefined_value();
26942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  while (current != undefined) {
26952ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Code* code = Code::cast(current);
26962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (IsMarked(code)) {
2697e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(code->is_weak_stub());
26982ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      IC::InvalidateMaps(code);
26992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
27002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    current = code->next_code_link();
27012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    code->set_next_code_link(undefined);
27022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
27032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org}
27042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
27052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
27063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid MarkCompactCollector::ClearDependentCode(DependentCode* entries) {
270779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_allocation;
27082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DependentCode::GroupStartIndexes starts(entries);
27092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int number_of_entries = starts.number_of_entries();
27102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (number_of_entries == 0) return;
27112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int g = DependentCode::kWeakICGroup;
27122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (starts.at(g) != starts.at(g + 1)) {
27132ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    int i = starts.at(g);
2714e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(i + 1 == starts.at(g + 1));
27152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Object* head = entries->object_at(i);
27162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ClearDependentICList(head);
27172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
27182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  g = DependentCode::kWeakCodeGroup;
27192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  for (int i = starts.at(g); i < starts.at(g + 1); i++) {
272041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    // If the entry is compilation info then the map must be alive,
27212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // and ClearDependentCode shouldn't be called.
2722e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(entries->is_code_at(i));
27232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    Code* code = entries->code_at(i);
27243d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    if (IsMarked(code) && !code->marked_for_deoptimization()) {
27255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      DependentCode::SetMarkedForDeoptimization(
27265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          code, static_cast<DependentCode::DependencyGroup>(g));
2727f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      code->InvalidateEmbeddedObjects();
27283d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org      have_code_to_deoptimize_ = true;
2729003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
27302ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
27312ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  for (int i = 0; i < number_of_entries; i++) {
273241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    entries->clear_at(i);
2733003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
2734003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
2735003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2736003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
27372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgint MarkCompactCollector::ClearNonLiveDependentCodeInGroup(
27382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    DependentCode* entries, int group, int start, int end, int new_start) {
27392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int survived = 0;
27402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (group == DependentCode::kWeakICGroup) {
27412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // Dependent weak IC stubs form a linked list and only the head is stored
27422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    // in the dependent code array.
27432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    if (start != end) {
2744e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(start + 1 == end);
27452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Object* old_head = entries->object_at(start);
27462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      MarkCompactWeakObjectRetainer retainer;
27471e4822ffed805d9cbb2a47cc9453aef06f3dfacamachenbach@chromium.org      Object* head = VisitWeakList<Code>(heap(), old_head, &retainer);
27482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      entries->set_object_at(new_start, head);
27492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Object** slot = entries->slot_at(new_start);
27502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      RecordSlot(slot, slot, head);
27512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      // We do not compact this group even if the head is undefined,
27522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      // more dependent ICs are likely to be added later.
27532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      survived = 1;
27542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
27552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  } else {
27562ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    for (int i = start; i < end; i++) {
275741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      Object* obj = entries->object_at(i);
2758e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(obj->IsCode() || IsMarked(obj));
275941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      if (IsMarked(obj) &&
2760fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org          (!obj->IsCode() || !WillBeDeoptimized(Code::cast(obj)))) {
27612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        if (new_start + survived != i) {
27622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          entries->set_object_at(new_start + survived, obj);
27632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        }
27642ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Object** slot = entries->slot_at(new_start + survived);
276541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org        RecordSlot(slot, slot, obj);
27662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        survived++;
2767003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      }
2768003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
27692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
27702ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  entries->set_number_of_entries(
27712ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      static_cast<DependentCode::DependencyGroup>(group), survived);
27722ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return survived;
27732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org}
27742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
27752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
27762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) {
27772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  DisallowHeapAllocation no_allocation;
27782ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  DependentCode::GroupStartIndexes starts(entries);
27792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int number_of_entries = starts.number_of_entries();
27802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (number_of_entries == 0) return;
27812ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  int new_number_of_entries = 0;
27822ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  // Go through all groups, remove dead codes and compact.
27832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  for (int g = 0; g < DependentCode::kGroupCount; g++) {
27842ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    int survived = ClearNonLiveDependentCodeInGroup(
27852ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        entries, g, starts.at(g), starts.at(g + 1), new_number_of_entries);
27862ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    new_number_of_entries += survived;
2787003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
27882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  for (int i = new_number_of_entries; i < number_of_entries; i++) {
278941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    entries->clear_at(i);
2790003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
2791003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
2792003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2793003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
2794ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MarkCompactCollector::ProcessWeakCollections() {
2795474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  GCTracer::Scope gc_scope(heap()->tracer(),
2796474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                           GCTracer::Scope::MC_WEAKCOLLECTION_PROCESS);
2797196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Object* weak_collection_obj = heap()->encountered_weak_collections();
2798ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  while (weak_collection_obj != Smi::FromInt(0)) {
2799ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    JSWeakCollection* weak_collection =
2800ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        reinterpret_cast<JSWeakCollection*>(weak_collection_obj);
2801e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(MarkCompactCollector::IsMarked(weak_collection));
2802e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    if (weak_collection->table()->IsHashTable()) {
2803e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table());
2804e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      Object** anchor = reinterpret_cast<Object**>(table->address());
2805e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      for (int i = 0; i < table->Capacity(); i++) {
2806e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org        if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
2807e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org          Object** key_slot =
2808e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org              table->RawFieldOfElementAt(ObjectHashTable::EntryToIndex(i));
2809e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org          RecordSlot(anchor, key_slot, *key_slot);
2810e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org          Object** value_slot =
2811e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org              table->RawFieldOfElementAt(ObjectHashTable::EntryToValueIndex(i));
28123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          MarkCompactMarkingVisitor::MarkObjectByPointer(this, anchor,
28133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                                         value_slot);
2814e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org        }
28157c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      }
28167c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    }
2817ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    weak_collection_obj = weak_collection->next();
28187c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  }
28197c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
28207c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
28217c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
2822ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MarkCompactCollector::ClearWeakCollections() {
2823474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  GCTracer::Scope gc_scope(heap()->tracer(),
2824474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                           GCTracer::Scope::MC_WEAKCOLLECTION_CLEAR);
2825196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  Object* weak_collection_obj = heap()->encountered_weak_collections();
2826ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  while (weak_collection_obj != Smi::FromInt(0)) {
2827ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    JSWeakCollection* weak_collection =
2828ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org        reinterpret_cast<JSWeakCollection*>(weak_collection_obj);
2829e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(MarkCompactCollector::IsMarked(weak_collection));
2830e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    if (weak_collection->table()->IsHashTable()) {
2831e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table());
2832e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      for (int i = 0; i < table->Capacity(); i++) {
2833e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org        HeapObject* key = HeapObject::cast(table->KeyAt(i));
2834e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org        if (!MarkCompactCollector::IsMarked(key)) {
2835e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org          table->RemoveEntry(i);
2836e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org        }
28377c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org      }
28387c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org    }
2839ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    weak_collection_obj = weak_collection->next();
2840e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    weak_collection->set_next(heap()->undefined_value());
28417c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  }
2842196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  heap()->set_encountered_weak_collections(Smi::FromInt(0));
28437c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org}
28447c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org
2845c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
28463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid MarkCompactCollector::AbortWeakCollections() {
28473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  GCTracer::Scope gc_scope(heap()->tracer(),
28483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                           GCTracer::Scope::MC_WEAKCOLLECTION_ABORT);
28493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Object* weak_collection_obj = heap()->encountered_weak_collections();
28503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  while (weak_collection_obj != Smi::FromInt(0)) {
28513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    JSWeakCollection* weak_collection =
28523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        reinterpret_cast<JSWeakCollection*>(weak_collection_obj);
28533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    weak_collection_obj = weak_collection->next();
28543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    weak_collection->set_next(heap()->undefined_value());
28553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  }
28563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  heap()->set_encountered_weak_collections(Smi::FromInt(0));
28573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
28583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
28593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org
2860975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgvoid MarkCompactCollector::RecordMigratedSlot(Object* value, Address slot) {
2861975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  if (heap_->InNewSpace(value)) {
2862975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    heap_->store_buffer()->Mark(slot);
2863975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) {
28643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_,
2865975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org                       reinterpret_cast<Object**>(slot),
2866975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org                       SlotsBuffer::IGNORE_OVERFLOW);
2867975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  }
2868975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org}
2869975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
2870975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org
2871c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// We scavange new space simultaneously with sweeping. This is done in two
2872c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// passes.
287343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
2874c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// The first pass migrates all alive objects from one semispace to another or
2875c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// promotes them to old space.  Forwarding address is written directly into
2876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// first word of object without any encoding.  If object is dead we write
2877c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// NULL as a forwarding address.
287843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
2879c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// The second pass updates pointers to new space in all spaces.  It is possible
2880c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// to encounter pointers to dead new space objects during traversal of pointers
2881c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// to new space.  We should clear them to avoid encountering them during next
2882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// pointer iteration.  This is an issue if the store buffer overflows and we
2883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// have to scan the entire old space, including dead objects, looking for
2884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// pointers to new space.
28853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgvoid MarkCompactCollector::MigrateObject(HeapObject* dst, HeapObject* src,
28863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                         int size, AllocationSpace dest) {
2887bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  Address dst_addr = dst->address();
2888bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  Address src_addr = src->address();
2889e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(heap()->AllowedToBeMigrated(src, dest));
2890e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize);
289183fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org  if (dest == OLD_POINTER_SPACE) {
2892bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    Address src_slot = src_addr;
2893bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    Address dst_slot = dst_addr;
2894e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsAligned(size, kPointerSize));
2895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2896c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    for (int remaining = size / kPointerSize; remaining > 0; remaining--) {
2897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Object* value = Memory::Object_at(src_slot);
2898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2899c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Memory::Object_at(dst_slot) = value;
2900c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
29012c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      if (!src->MayContainRawValues()) {
2902975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org        RecordMigratedSlot(value, dst_slot);
2903c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
290443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2905c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      src_slot += kPointerSize;
2906c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      dst_slot += kPointerSize;
290743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
290843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2909bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    if (compacting_ && dst->IsJSFunction()) {
2910bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org      Address code_entry_slot = dst_addr + JSFunction::kCodeEntryOffset;
2911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Address code_entry = Memory::Address_at(code_entry_slot);
291243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) {
29143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_,
29153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                           SlotsBuffer::CODE_ENTRY_SLOT, code_entry_slot,
2916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           SlotsBuffer::IGNORE_OVERFLOW);
291743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
2918975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    } else if (dst->IsConstantPoolArray()) {
29192c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      // We special case ConstantPoolArrays since they could contain integers
29202c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      // value entries which look like tagged pointers.
29212c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      // TODO(mstarzinger): restructure this code to avoid this special-casing.
2922196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      ConstantPoolArray* array = ConstantPoolArray::cast(dst);
2923196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      ConstantPoolArray::Iterator code_iter(array, ConstantPoolArray::CODE_PTR);
2924196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      while (!code_iter.is_finished()) {
2925bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org        Address code_entry_slot =
2926196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org            dst_addr + array->OffsetOfElementAt(code_iter.next_index());
2927bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org        Address code_entry = Memory::Address_at(code_entry_slot);
2928bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
2929bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org        if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) {
29303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_,
29313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                             SlotsBuffer::CODE_ENTRY_SLOT, code_entry_slot,
2932bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org                             SlotsBuffer::IGNORE_OVERFLOW);
2933bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org        }
2934bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org      }
2935975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org      ConstantPoolArray::Iterator heap_iter(array, ConstantPoolArray::HEAP_PTR);
2936975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org      while (!heap_iter.is_finished()) {
2937975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org        Address heap_slot =
2938975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org            dst_addr + array->OffsetOfElementAt(heap_iter.next_index());
2939975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org        Object* value = Memory::Object_at(heap_slot);
2940975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org        RecordMigratedSlot(value, heap_slot);
2941975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org      }
294243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
2943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (dest == CODE_SPACE) {
2944bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr));
2945bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    heap()->MoveBlock(dst_addr, src_addr, size);
29463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_,
29473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                       SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr,
2948c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       SlotsBuffer::IGNORE_OVERFLOW);
2949bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    Code::cast(dst)->Relocate(dst_addr - src_addr);
295030ce411529579186181838984710b0b0980857aaricow@chromium.org  } else {
2951e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(dest == OLD_DATA_SPACE || dest == NEW_SPACE);
2952bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    heap()->MoveBlock(dst_addr, src_addr, size);
295330ce411529579186181838984710b0b0980857aaricow@chromium.org  }
29544b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  heap()->OnMoveEvent(dst, src, size);
2955bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  Memory::Address_at(src_addr) = dst_addr;
2956b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
2957b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
2958b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
2959b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org// Visitor for updating pointers from live objects in old spaces to new space.
2960b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org// It does not expect to encounter pointers to dead objects.
29613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass PointersUpdatingVisitor : public ObjectVisitor {
2962b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org public:
29633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) {}
2964ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
29653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  void VisitPointer(Object** p) { UpdatePointer(p); }
2966b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
29672ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org  void VisitPointers(Object** start, Object** end) {
29682ab0c3bc2d6dc2b2f91f02efe38d1a3e5a0e3f4cdanno@chromium.org    for (Object** p = start; p < end; p++) UpdatePointer(p);
2969c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
2970c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2971b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void VisitEmbeddedPointer(RelocInfo* rinfo) {
2972e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
2973b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    Object* target = rinfo->target_object();
297489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    Object* old_target = target;
2975b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    VisitPointer(&target);
297689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    // Avoid unnecessary changes that might unnecessary flush the instruction
297789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    // cache.
297889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    if (target != old_target) {
297989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      rinfo->set_target_object(target);
298089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    }
2981b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
2982b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
2983b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  void VisitCodeTarget(RelocInfo* rinfo) {
2984e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
2985b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
298689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    Object* old_target = target;
2987b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    VisitPointer(&target);
298889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    if (target != old_target) {
298989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org      rinfo->set_target_address(Code::cast(target)->instruction_start());
299089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org    }
2991b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
2992b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
2993e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  void VisitCodeAgeSequence(RelocInfo* rinfo) {
2994e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
2995e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    Object* stub = rinfo->code_age_stub();
2996e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(stub != NULL);
2997e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    VisitPointer(&stub);
2998e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    if (stub != rinfo->code_age_stub()) {
2999e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org      rinfo->set_code_age_stub(Code::cast(stub));
3000e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    }
3001e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  }
3002e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
3003b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  void VisitDebugTarget(RelocInfo* rinfo) {
3004e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((RelocInfo::IsJSReturn(rinfo->rmode()) &&
30052356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org            rinfo->IsPatchedReturnSequence()) ||
30062356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org           (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
30072356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org            rinfo->IsPatchedDebugBreakSlotSequence()));
3008b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
3009b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    VisitPointer(&target);
3010b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    rinfo->set_call_address(Code::cast(target)->instruction_start());
3011b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
3012e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
3013c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static inline void UpdateSlot(Heap* heap, Object** slot) {
3014c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Object* obj = *slot;
3015c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3016c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!obj->IsHeapObject()) return;
3017c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3018c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    HeapObject* heap_obj = HeapObject::cast(obj);
3019c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3020c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MapWord map_word = heap_obj->map_word();
3021c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (map_word.IsForwardingAddress()) {
3022e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(heap->InFromSpace(heap_obj) ||
3023c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com             MarkCompactCollector::IsOnEvacuationCandidate(heap_obj));
3024c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HeapObject* target = map_word.ToForwardingAddress();
3025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      *slot = target;
3026e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!heap->InFromSpace(target) &&
3027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com             !MarkCompactCollector::IsOnEvacuationCandidate(target));
3028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3029c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3030c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3031ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org private:
30323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  inline void UpdatePointer(Object** p) { UpdateSlot(heap_, p); }
3033c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3034ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap_;
3035b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org};
3036b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
303730ce411529579186181838984710b0b0980857aaricow@chromium.org
30389e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.orgstatic void UpdatePointer(HeapObject** address, HeapObject* object) {
30399e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  Address new_addr = Memory::Address_at(object->address());
3040b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3041c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The new space sweep will overwrite the map word of dead objects
3042c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // with NULL. In this case we do not need to transfer this entry to
3043c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the store buffer which we are rebuilding.
30449e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  // We perform the pointer update with a no barrier compare-and-swap. The
30459e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  // compare and swap may fail in the case where the pointer update tries to
30469e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  // update garbage memory which was concurrently accessed by the sweeper.
3047c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (new_addr != NULL) {
30481e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    base::NoBarrier_CompareAndSwap(
30491e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        reinterpret_cast<base::AtomicWord*>(address),
30501e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        reinterpret_cast<base::AtomicWord>(object),
30511e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org        reinterpret_cast<base::AtomicWord>(HeapObject::FromAddress(new_addr)));
305230ce411529579186181838984710b0b0980857aaricow@chromium.org  }
3053b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
3054b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3055b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3056c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic String* UpdateReferenceInExternalStringTableEntry(Heap* heap,
3057c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                         Object** p) {
3058c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MapWord map_word = HeapObject::cast(*p)->map_word();
3059c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (map_word.IsForwardingAddress()) {
3061c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return String::cast(map_word.ToForwardingAddress());
3062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return String::cast(*p);
3065b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
3066b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3067b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MarkCompactCollector::TryPromoteObject(HeapObject* object,
3069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                            int object_size) {
3070e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
3071b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
307283fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org  OldSpace* target_space = heap()->TargetSpace(object);
307383fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org
3074e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(target_space == heap()->old_pointer_space() ||
307583fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org         target_space == heap()->old_data_space());
3076a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  HeapObject* target;
3077a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  AllocationResult allocation = target_space->AllocateRaw(object_size);
3078a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  if (allocation.To(&target)) {
30793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    MigrateObject(target, object, object_size, target_space->identity());
30806a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    heap()->IncrementPromotedObjectsSize(object_size);
308183fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org    return true;
3082b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
3083b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3084b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  return false;
3085b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org}
3086b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3087b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EvacuateNewSpace() {
3089ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // There are soft limits in the allocation code, designed trigger a mark
3090ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // sweep collection by failing allocations.  But since we are already in
3091ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org  // a mark-sweep allocation, there is no sense in trying to trigger one.
30925697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  AlwaysAllocateScope scope(isolate());
3093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  NewSpace* new_space = heap()->new_space();
3095b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3096c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Store allocation range before flipping semispaces.
3097c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address from_bottom = new_space->bottom();
3098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address from_top = new_space->top();
3099b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3100b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  // Flip the semispaces.  After flipping, to space is empty, from space has
3101b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  // live objects.
3102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  new_space->Flip();
3103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  new_space->ResetAllocationInfo();
3104b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3105b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  int survivors_size = 0;
3106b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3107b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  // First pass: traverse all objects in inactive semispace, remove marks,
3108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // migrate live objects and write forwarding addresses.  This stage puts
3109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // new entries in the store buffer and may cause some pages to be marked
3110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // scan-on-scavenge.
3111169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NewSpacePageIterator it(from_bottom, from_top);
3112169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  while (it.has_next()) {
3113169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    NewSpacePage* p = it.next();
3114975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org    survivors_size += DiscoverAndEvacuateBlackObjectsOnPage(new_space, p);
3115b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  }
3116b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap_->IncrementYoungSurvivorsCounter(survivors_size);
3118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  new_space->set_age_mark(new_space->top());
3119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3120b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
31214a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
3122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) {
31235697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  AlwaysAllocateScope always_allocate(isolate());
3124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3125e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(p->IsEvacuationCandidate() && !p->WasSwept());
3126a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  p->SetWasSwept();
3127b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int offsets[16];
312943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
313010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) {
313110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    Address cell_base = it.CurrentCellBase();
313210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    MarkBit::CellType* cell = it.CurrentCell();
313310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org
313410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    if (*cell == 0) continue;
313543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
313610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    int live_objects = MarkWordToObjectStarts(*cell, offsets);
3137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    for (int i = 0; i < live_objects; i++) {
3138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Address object_addr = cell_base + offsets[i] * kPointerSize;
3139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HeapObject* object = HeapObject::FromAddress(object_addr);
3140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
3141013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
3142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int size = object->Size();
3143013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
3144a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      HeapObject* target_object;
3145a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      AllocationResult allocation = space->AllocateRaw(size);
3146a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      if (!allocation.To(&target_object)) {
3147f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org        // If allocation failed, use emergency memory and re-try allocation.
3148f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org        CHECK(space->HasEmergencyMemory());
3149f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org        space->UseEmergencyMemory();
3150f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org        allocation = space->AllocateRaw(size);
3151f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org      }
3152f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org      if (!allocation.To(&target_object)) {
3153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // OS refused to give us memory.
3154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        V8::FatalProcessOutOfMemory("Evacuation");
3155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        return;
3156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
3157013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
3158a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org      MigrateObject(target_object, object, size, space->identity());
3159e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(object->map_word().IsForwardingAddress());
3160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3161013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
3162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Clear marking bits for current cell.
316310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    *cell = 0;
3164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  p->ResetLiveBytes();
3166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3167013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
316843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EvacuatePages() {
3170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int npages = evacuation_candidates_.length();
3171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int i = 0; i < npages; i++) {
3172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* p = evacuation_candidates_[i];
3173e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(p->IsEvacuationCandidate() ||
31743484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org           p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
3175e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(static_cast<int>(p->parallel_sweeping()) ==
3176474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org           MemoryChunk::SWEEPING_DONE);
3177f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org    PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3178f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org    // Allocate emergency memory for the case when compaction fails due to out
3179f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org    // of memory.
3180f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org    if (!space->HasEmergencyMemory()) {
3181f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org      space->CreateEmergencyMemory();
3182f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org    }
3183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (p->IsEvacuationCandidate()) {
3184f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org      // During compaction we might have to request a new page. Check that we
3185f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org      // have an emergency page and the space still has room for that.
3186f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org      if (space->HasEmergencyMemory() && space->CanExpand()) {
3187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        EvacuateLiveObjectsFromPage(p);
318843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      } else {
3189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Without room for expansion evacuation is not guaranteed to succeed.
3190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Pessimistically abandon unevacuated pages.
3191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        for (int j = i; j < npages; j++) {
3192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          Page* page = evacuation_candidates_[j];
3193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address());
3194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          page->ClearEvacuationCandidate();
3195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          page->SetFlag(Page::RESCAN_ON_EVACUATION);
319643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        }
3197f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org        break;
3198f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org      }
3199f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org    }
3200f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org  }
3201f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org  if (npages > 0) {
3202f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org    // Release emergency memory.
3203f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org    PagedSpaces spaces(heap());
3204f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org    for (PagedSpace* space = spaces.next(); space != NULL;
3205f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org         space = spaces.next()) {
3206f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org      if (space->HasEmergencyMemory()) {
3207f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org        space->FreeEmergencyMemory();
320843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
320943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
3210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
321243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3213013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
3214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass EvacuationWeakObjectRetainer : public WeakObjectRetainer {
3215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public:
3216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  virtual Object* RetainAs(Object* object) {
3217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (object->IsHeapObject()) {
3218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HeapObject* heap_object = HeapObject::cast(object);
3219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      MapWord map_word = heap_object->map_word();
3220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (map_word.IsForwardingAddress()) {
3221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        return map_word.ToForwardingAddress();
3222013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org      }
3223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return object;
3225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com};
3227013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
3228013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
32293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic inline void UpdateSlot(Isolate* isolate, ObjectVisitor* v,
32303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                              SlotsBuffer::SlotType slot_type, Address addr) {
3231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  switch (slot_type) {
3232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    case SlotsBuffer::CODE_TARGET_SLOT: {
3233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RelocInfo rinfo(addr, RelocInfo::CODE_TARGET, 0, NULL);
3234e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      rinfo.Visit(isolate, v);
3235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      break;
3236013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org    }
3237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    case SlotsBuffer::CODE_ENTRY_SLOT: {
3238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      v->VisitCodeEntry(addr);
3239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      break;
3240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    case SlotsBuffer::RELOCATED_CODE_OBJECT: {
3242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HeapObject* obj = HeapObject::FromAddress(addr);
3243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Code::cast(obj)->CodeIterateBody(v);
3244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      break;
3245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    case SlotsBuffer::DEBUG_TARGET_SLOT: {
3247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RelocInfo rinfo(addr, RelocInfo::DEBUG_BREAK_SLOT, 0, NULL);
3248e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      if (rinfo.IsPatchedDebugBreakSlotSequence()) rinfo.Visit(isolate, v);
3249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      break;
3250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    case SlotsBuffer::JS_RETURN_SLOT: {
3252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RelocInfo rinfo(addr, RelocInfo::JS_RETURN, 0, NULL);
3253e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(isolate, v);
3254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      break;
3255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3256b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    case SlotsBuffer::EMBEDDED_OBJECT_SLOT: {
3257b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      RelocInfo rinfo(addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL);
3258e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org      rinfo.Visit(isolate, v);
3259b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      break;
3260b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
3261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    default:
3262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      UNREACHABLE();
3263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      break;
3264013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org  }
3265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
3266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3267013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
32683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgenum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS };
3269013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
3270013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
32713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgenum SkipListRebuildingMode { REBUILD_SKIP_LIST, IGNORE_SKIP_LIST };
3272013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
3273013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org
32743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgenum FreeSpaceTreatmentMode { IGNORE_FREE_SPACE, ZAP_FREE_SPACE };
3275f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3276f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
32773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <MarkCompactCollector::SweepingParallelism mode>
32783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic intptr_t Free(PagedSpace* space, FreeList* free_list, Address start,
3279474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                     int size) {
3280474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  if (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD) {
3281e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(free_list == NULL);
3282474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    return space->Free(start, size);
3283474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  } else {
3284474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    // TODO(hpayer): account for wasted bytes in concurrent sweeping too.
3285474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    return size - free_list->Free(start, size);
3286474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
3287474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
3288474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
3289474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
3290a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org// Sweeps a page. After sweeping the page can be iterated.
3291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Slots in live objects pointing into evacuation candidates are updated
3292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// if requested.
3293474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org// Returns the size of the biggest continuous freed memory chunk in bytes.
32943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgtemplate <SweepingMode sweeping_mode,
32953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          MarkCompactCollector::SweepingParallelism parallelism,
32963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          SkipListRebuildingMode skip_list_mode,
32973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          FreeSpaceTreatmentMode free_space_mode>
3298a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgstatic int Sweep(PagedSpace* space, FreeList* free_list, Page* p,
3299a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                 ObjectVisitor* v) {
3300e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!p->IsEvacuationCandidate() && !p->WasSwept());
3301e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST,
3302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            space->identity() == CODE_SPACE);
3303e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST));
3304e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD ||
3305474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org         sweeping_mode == SWEEP_ONLY);
3306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3307ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  Address free_start = p->area_start();
3308e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
3309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int offsets[16];
3310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SkipList* skip_list = p->skip_list();
3312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int curr_region = -1;
3313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) {
3314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    skip_list->Clear();
3315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3317474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  intptr_t freed_bytes = 0;
3318474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  intptr_t max_freed_bytes = 0;
3319474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
332010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) {
332110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    Address cell_base = it.CurrentCellBase();
332210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    MarkBit::CellType* cell = it.CurrentCell();
332310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    int live_objects = MarkWordToObjectStarts(*cell, offsets);
3324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int live_index = 0;
33253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    for (; live_objects != 0; live_objects--) {
332610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org      Address free_end = cell_base + offsets[live_index++] * kPointerSize;
3327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (free_end != free_start) {
3328474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        int size = static_cast<int>(free_end - free_start);
3329f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        if (free_space_mode == ZAP_FREE_SPACE) {
3330474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          memset(free_start, 0xcc, size);
3331f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        }
3332474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        freed_bytes = Free<parallelism>(space, free_list, free_start, size);
3333474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3334c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#ifdef ENABLE_GDB_JIT_INTERFACE
3335c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org        if (FLAG_gdbjit && space->identity() == CODE_SPACE) {
3336c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org          GDBJITInterface::RemoveCodeRange(free_start, free_end);
3337c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org        }
3338c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#endif
3339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
3340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      HeapObject* live_object = HeapObject::FromAddress(free_end);
3341e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(Marking::IsBlack(Marking::MarkBitFrom(live_object)));
3342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Map* map = live_object->map();
3343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int size = live_object->SizeFromMap(map);
3344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) {
3345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        live_object->IterateBody(map->instance_type(), size, v);
3346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
3347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) {
33483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        int new_region_start = SkipList::RegionNumber(free_end);
3349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        int new_region_end =
3350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            SkipList::RegionNumber(free_end + size - kPointerSize);
33513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        if (new_region_start != curr_region || new_region_end != curr_region) {
3352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          skip_list->AddObject(free_end, size);
3353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          curr_region = new_region_end;
3354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
3355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
3356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      free_start = free_end + size;
335743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
3358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Clear marking bits for current cell.
335910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org    *cell = 0;
336043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
3361ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  if (free_start != p->area_end()) {
3362474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    int size = static_cast<int>(p->area_end() - free_start);
3363f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (free_space_mode == ZAP_FREE_SPACE) {
3364474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      memset(free_start, 0xcc, size);
3365f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
3366474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    freed_bytes = Free<parallelism>(space, free_list, free_start, size);
3367474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3368c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#ifdef ENABLE_GDB_JIT_INTERFACE
3369c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    if (FLAG_gdbjit && space->identity() == CODE_SPACE) {
3370c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org      GDBJITInterface::RemoveCodeRange(free_start, p->area_end());
3371c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    }
3372c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#endif
3373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  p->ResetLiveBytes();
33757c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org
33767c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  if (parallelism == MarkCompactCollector::SWEEP_IN_PARALLEL) {
33777c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    // When concurrent sweeping is active, the page will be marked after
33787c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    // sweeping by the main thread.
33797c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE);
33807c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  } else {
3381a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    p->SetWasSwept();
33827c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  }
3383474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes));
338443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
338543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
338643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) {
3388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Page* p = Page::FromAddress(code->address());
33899258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
33903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  if (p->IsEvacuationCandidate() || p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
3391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return false;
3392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
339343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address code_start = code->address();
3395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Address code_end = code_start + code->Size();
339643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  uint32_t start_index = MemoryChunk::FastAddressToMarkbitIndex(code_start);
3398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  uint32_t end_index =
3399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      MemoryChunk::FastAddressToMarkbitIndex(code_end - kPointerSize);
3400defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
3401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Bitmap* b = p->markbits();
3402defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
3403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkBit start_mark_bit = b->MarkBitFromIndex(start_index);
3404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkBit end_mark_bit = b->MarkBitFromIndex(end_index);
340543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkBit::CellType* start_cell = start_mark_bit.cell();
3407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkBit::CellType* end_cell = end_mark_bit.cell();
340843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (value) {
3410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit::CellType start_mask = ~(start_mark_bit.mask() - 1);
3411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit::CellType end_mask = (end_mark_bit.mask() << 1) - 1;
341243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (start_cell == end_cell) {
3414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      *start_cell |= start_mask & end_mask;
3415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
3416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      *start_cell |= start_mask;
3417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      for (MarkBit::CellType* cell = start_cell + 1; cell < end_cell; cell++) {
3418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        *cell = ~0;
3419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
3420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      *end_cell |= end_mask;
3421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
3422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
34233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    for (MarkBit::CellType* cell = start_cell; cell <= end_cell; cell++) {
3424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      *cell = 0;
3425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
34260c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
34270c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return true;
3429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
34300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
34310c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic bool IsOnInvalidatedCodeObject(Address addr) {
3433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // We did not record any slots in large objects thus
3434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // we can safely go to the page from the slot address.
3435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Page* p = Page::FromAddress(addr);
34360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // First check owner's identity because old pointer and old data spaces
3438c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // are swept lazily and might still have non-zero mark-bits on some
3439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // pages.
3440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (p->owner()->identity() != CODE_SPACE) return false;
34410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // In code space only bits on evacuation candidates (but we don't record
3443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // any slots on them) and under invalidated code objects are non-zero.
3444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkBit mark_bit =
3445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr));
34460c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return mark_bit.Get();
3448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
34490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
34500c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::InvalidateCode(Code* code) {
3452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (heap_->incremental_marking()->IsCompacting() &&
3453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !ShouldSkipEvacuationSlotRecording(code)) {
3454e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(compacting_);
34550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the object is white than no slots were recorded on it yet.
3457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MarkBit mark_bit = Marking::MarkBitFrom(code);
3458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (Marking::IsWhite(mark_bit)) return;
34590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    invalidated_code_.Add(code);
34610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
3462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
34630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3464c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
3465fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// Return true if the given code is deoptimized or will be deoptimized.
3466fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgbool MarkCompactCollector::WillBeDeoptimized(Code* code) {
34672ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return code->is_optimized_code() && code->marked_for_deoptimization();
3468fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
3469fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
3470fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
3471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MarkCompactCollector::MarkInvalidatedCode() {
3472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool code_marked = false;
34730c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3474c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int length = invalidated_code_.length();
3475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int i = 0; i < length; i++) {
3476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Code* code = invalidated_code_[i];
3477ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
3478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (SetMarkBitsUnderInvalidatedCode(code, true)) {
3479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      code_marked = true;
34800c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
3481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
34820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return code_marked;
3484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
34850c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
34860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::RemoveDeadInvalidatedCode() {
3488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int length = invalidated_code_.length();
3489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int i = 0; i < length; i++) {
3490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!IsMarked(invalidated_code_[i])) invalidated_code_[i] = NULL;
3491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3492c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
34930c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
34940c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::ProcessInvalidatedCode(ObjectVisitor* visitor) {
3496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int length = invalidated_code_.length();
3497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int i = 0; i < length; i++) {
3498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Code* code = invalidated_code_[i];
3499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (code != NULL) {
3500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      code->Iterate(visitor);
3501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SetMarkBitsUnderInvalidatedCode(code, false);
35020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
35030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
3504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  invalidated_code_.Rewind(0);
3505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
35060c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
35070c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
3509ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Heap::RelocationLock relocation_lock(heap());
3510ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
35111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  bool code_slots_filtering_required;
35123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
35133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope gc_scope(heap()->tracer(),
3514474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                             GCTracer::Scope::MC_SWEEP_NEWSPACE);
35151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    code_slots_filtering_required = MarkInvalidatedCode();
35161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    EvacuateNewSpace();
35171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
35180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
35193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
35203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope gc_scope(heap()->tracer(),
3521474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                             GCTracer::Scope::MC_EVACUATE_PAGES);
35221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    EvacuatePages();
35231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
3524b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
3525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Second pass: find pointers to new space and update them.
3526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PointersUpdatingVisitor updating_visitor(heap());
3527b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org
35283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
35293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope gc_scope(heap()->tracer(),
35301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                             GCTracer::Scope::MC_UPDATE_NEW_TO_NEW_POINTERS);
35311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Update pointers in to space.
35321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    SemiSpaceIterator to_it(heap()->new_space()->bottom(),
35331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                            heap()->new_space()->top());
35343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    for (HeapObject* object = to_it.Next(); object != NULL;
35351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org         object = to_it.Next()) {
35361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Map* map = object->map();
35373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      object->IterateBody(map->instance_type(), object->SizeFromMap(map),
35381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                          &updating_visitor);
35391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
3540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
35410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
35423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
35433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope gc_scope(heap()->tracer(),
35441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                             GCTracer::Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS);
35451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    // Update roots.
35461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE);
35471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
35480c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
35493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
35503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope gc_scope(heap()->tracer(),
35511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                             GCTracer::Scope::MC_UPDATE_OLD_TO_NEW_POINTERS);
35523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    StoreBufferRebuildScope scope(heap_, heap_->store_buffer(),
3553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  &Heap::ScavengeStoreBufferCallback);
3554169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    heap_->store_buffer()->IteratePointersToNewSpaceAndClearMaps(
3555169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org        &UpdatePointer);
3556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
3557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
35583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
35593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope gc_scope(heap()->tracer(),
35601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                             GCTracer::Scope::MC_UPDATE_POINTERS_TO_EVACUATED);
35613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    SlotsBuffer::UpdateSlotsRecordedIn(heap_, migration_slots_buffer_,
35621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                       code_slots_filtering_required);
35631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (FLAG_trace_fragmentation) {
35641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      PrintF("  migration slots buffer: %d\n",
35651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org             SlotsBuffer::SizeOfChain(migration_slots_buffer_));
35661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
35671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
35681b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    if (compacting_ && was_marked_incrementally_) {
35691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      // It's difficult to filter out slots recorded for large objects.
35701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      LargeObjectIterator it(heap_->lo_space());
35711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
35721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // LargeObjectSpace is not swept yet thus we have to skip
35731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // dead objects explicitly.
35741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (!IsMarked(obj)) continue;
35751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
35761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        Page* p = Page::FromAddress(obj->address());
35771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
35781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          obj->Iterate(&updating_visitor);
35791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          p->ClearFlag(Page::RESCAN_ON_EVACUATION);
35801b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
3581c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
3582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
35830c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
35840c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int npages = evacuation_candidates_.length();
35863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
35873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope gc_scope(
35883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        heap()->tracer(),
35893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        GCTracer::Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED);
35901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    for (int i = 0; i < npages; i++) {
35911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      Page* p = evacuation_candidates_[i];
3592e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(p->IsEvacuationCandidate() ||
35931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org             p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
35941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
35951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      if (p->IsEvacuationCandidate()) {
35963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        SlotsBuffer::UpdateSlotsRecordedIn(heap_, p->slots_buffer(),
35971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                                           code_slots_filtering_required);
35981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (FLAG_trace_fragmentation) {
35993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          PrintF("  page %p slots buffer: %d\n", reinterpret_cast<void*>(p),
36001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                 SlotsBuffer::SizeOfChain(p->slots_buffer()));
36011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
3602c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
36031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // Important: skip list should be cleared only after roots were updated
36041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // because root iteration traverses the stack and might have to find
36051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        // code objects from non-updated pc pointing into evacuation candidate.
36061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        SkipList* list = p->skip_list();
36071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (list != NULL) list->Clear();
36081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      } else {
36091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (FLAG_gc_verbose) {
36101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
36111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                 reinterpret_cast<intptr_t>(p));
36121b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
36131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        PagedSpace* space = static_cast<PagedSpace*>(p->owner());
36141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
36151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
36161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        switch (space->identity()) {
36171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          case OLD_DATA_SPACE:
3618a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3619a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                  IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
3620a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                                                       &updating_visitor);
36211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            break;
36221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          case OLD_POINTER_SPACE:
3623a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3624a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                  IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
3625a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                                                       &updating_visitor);
36261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            break;
36271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          case CODE_SPACE:
3628f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            if (FLAG_zap_code_space) {
3629a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org              Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3630a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                    REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, NULL, p,
3631a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                                                       &updating_visitor);
3632f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            } else {
3633a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org              Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3634a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                    REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
3635a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                                                          &updating_visitor);
3636f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org            }
36371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            break;
36381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          default:
36391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            UNREACHABLE();
36401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org            break;
36411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
36420c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      }
36430c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
36440c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
36450c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3646474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  GCTracer::Scope gc_scope(heap()->tracer(),
3647474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                           GCTracer::Scope::MC_UPDATE_MISC_POINTERS);
36481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
3649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Update pointers from cells.
3650c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  HeapObjectIterator cell_iterator(heap_->cell_space());
36513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (HeapObject* cell = cell_iterator.Next(); cell != NULL;
3652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       cell = cell_iterator.Next()) {
365341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    if (cell->IsCell()) {
36541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      Cell::BodyDescriptor::IterateBody(cell, &updating_visitor);
365541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
365641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
365741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
365841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  HeapObjectIterator js_global_property_cell_iterator(
365941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      heap_->property_cell_space());
36603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  for (HeapObject* cell = js_global_property_cell_iterator.Next(); cell != NULL;
366141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org       cell = js_global_property_cell_iterator.Next()) {
3662b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    if (cell->IsPropertyCell()) {
36631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor);
36640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
36650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
36660c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
36674a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  heap_->string_table()->Iterate(&updating_visitor);
366825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  updating_visitor.VisitPointer(heap_->weak_object_to_code_table_address());
366925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  if (heap_->weak_object_to_code_table()->IsHashTable()) {
367025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    WeakHashTable* table =
367125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org        WeakHashTable::cast(heap_->weak_object_to_code_table());
367225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    table->Iterate(&updating_visitor);
3673865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    table->Rehash(heap_->isolate()->factory()->undefined_value());
367425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
36750c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3676c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Update pointers from external string table.
3677c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap_->UpdateReferencesInExternalStringTable(
3678c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      &UpdateReferenceInExternalStringTableEntry);
367930ce411529579186181838984710b0b0980857aaricow@chromium.org
3680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  EvacuationWeakObjectRetainer evacuation_object_retainer;
3681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap()->ProcessWeakReferences(&evacuation_object_retainer);
36820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Visit invalidated code (we ignored all slots on it) and clear mark-bits
3684c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // under it.
3685c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ProcessInvalidatedCode(&updating_visitor);
36860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
368788d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org  heap_->isolate()->inner_pointer_to_code_cache()->Flush();
368888d326b0935b802e71e3a75e02f31fae8c2af96cmstarzinger@chromium.org
3689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_);
3690e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(migration_slots_buffer_ == NULL);
36912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
36922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
36932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
36943484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orgvoid MarkCompactCollector::MoveEvacuationCandidatesToEndOfPagesList() {
36956e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  int npages = evacuation_candidates_.length();
36966e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  for (int i = 0; i < npages; i++) {
36976e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    Page* p = evacuation_candidates_[i];
36986e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    if (!p->IsEvacuationCandidate()) continue;
36996e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org    p->Unlink();
37003484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    PagedSpace* space = static_cast<PagedSpace*>(p->owner());
37013484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    p->InsertAfter(space->LastPage());
37026e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  }
37036e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org}
37046e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
37056e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
37062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgvoid MarkCompactCollector::ReleaseEvacuationCandidates() {
37072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  int npages = evacuation_candidates_.length();
3708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int i = 0; i < npages; i++) {
3709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* p = evacuation_candidates_[i];
3710c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!p->IsEvacuationCandidate()) continue;
3711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3712ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    space->Free(p->area_start(), p->area_size());
3713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    p->set_scan_on_scavenge(false);
3714c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address());
3715994edf6a113fb3651536b60073df05a72a95f77erossberg@chromium.org    p->ResetLiveBytes();
37163484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    space->ReleasePage(p);
37170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
3718c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  evacuation_candidates_.Rewind(0);
3719c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  compacting_ = false;
37206e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  heap()->FreeQueuedChunks();
372143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
372243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
372343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3724c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kStartTableEntriesPerLine = 5;
3725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kStartTableLines = 171;
3726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kStartTableInvalidLine = 127;
3727c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kStartTableUnusedEntry = 126;
3728c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3729c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#define _ kStartTableUnusedEntry
3730c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#define X kStartTableInvalidLine
3731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Mark-bit to object start offset table.
3732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com//
3733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// The line is indexed by the mark bits in a byte.  The first number on
3734c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// the line describes the number of live object starts for the line and the
3735c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// other numbers on the line describe the offsets (in words) of the object
3736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// starts.
3737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com//
3738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Since objects are at least 2 words large we don't have entries for two
3739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// consecutive 1 bits.  All entries after 170 have at least 2 consecutive bits.
3740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comchar kStartTable[kStartTableLines * kStartTableEntriesPerLine] = {
37413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    0, _, _,
37423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 0
37433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    1, 0, _,
37443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 1
37453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    1, 1, _,
37463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 2
37473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 3
37493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    1, 2, _,
37503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 4
37513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 0, 2,
37523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 5
37533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 6
37553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 7
37573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    1, 3, _,
37583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 8
37593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 0, 3,
37603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 9
37613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 1, 3,
37623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 10
37633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 11
37653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 12
37673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 13
37693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 14
37713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 15
37733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    1, 4, _,
37743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 16
37753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 0, 4,
37763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 17
37773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 1, 4,
37783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 18
37793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 19
37813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 2, 4,
37823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 20
37833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 2,
37843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    4, _,  // 21
37853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 22
37873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 23
37893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 24
37913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 25
37933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 26
37953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 27
37973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
37983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 28
37993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 29
38013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 30
38033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 31
38053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    1, 5, _,
38063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 32
38073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 0, 5,
38083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 33
38093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 1, 5,
38103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 34
38113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 35
38133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 2, 5,
38143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 36
38153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 2,
38163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    5, _,  // 37
38173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 38
38193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 39
38213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 3, 5,
38223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 40
38233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 3,
38243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    5, _,  // 41
38253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 1, 3,
38263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    5, _,  // 42
38273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 43
38293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 44
38313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 45
38333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 46
38353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 47
38373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 48
38393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 49
38413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 50
38433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 51
38453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 52
38473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 53
38493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 54
38513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 55
38533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 56
38553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 57
38573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 58
38593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 59
38613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 60
38633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 61
38653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 62
38673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 63
38693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    1, 6, _,
38703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 64
38713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 0, 6,
38723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 65
38733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 1, 6,
38743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 66
38753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 67
38773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 2, 6,
38783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 68
38793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 2,
38803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    6, _,  // 69
38813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 70
38833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 71
38853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 3, 6,
38863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 72
38873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 3,
38883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    6, _,  // 73
38893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 1, 3,
38903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    6, _,  // 74
38913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 75
38933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 76
38953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 77
38973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
38983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 78
38993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 79
39013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 4, 6,
39023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 80
39033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 4,
39043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    6, _,  // 81
39053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 1, 4,
39063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    6, _,  // 82
39073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 83
39093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 2, 4,
39103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    6, _,  // 84
39113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    4, 0, 2,
39123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    4, 6,  // 85
39133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 86
39153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 87
39173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 88
39193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 89
39213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 90
39233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 91
39253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 92
39273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 93
39293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 94
39313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 95
39333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 96
39353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 97
39373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 98
39393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 99
39413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 100
39433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 101
39453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 102
39473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 103
39493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 104
39513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 105
39533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 106
39553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 107
39573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 108
39593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 109
39613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 110
39633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 111
39653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 112
39673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 113
39693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 114
39713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 115
39733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 116
39753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 117
39773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 118
39793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 119
39813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 120
39833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 121
39853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 122
39873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 123
39893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 124
39913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39923e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 125
39933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 126
39953e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
39963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 127
39973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    1, 7, _,
39983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 128
39993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 0, 7,
40003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 129
40013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 1, 7,
40023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 130
40033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 131
40053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 2, 7,
40063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 132
40073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 2,
40083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 133
40093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 134
40113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40123e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 135
40133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 3, 7,
40143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 136
40153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 3,
40163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 137
40173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 1, 3,
40183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 138
40193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 139
40213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 140
40233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 141
40253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 142
40273e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 143
40293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 4, 7,
40303e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 144
40313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 4,
40323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 145
40333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 1, 4,
40343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 146
40353e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 147
40373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 2, 4,
40383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 148
40393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    4, 0, 2,
40403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    4, 7,  // 149
40413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 150
40433e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 151
40453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 152
40473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 153
40493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 154
40513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 155
40533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 156
40553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 157
40573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 158
40593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 159
40613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    2, 5, 7,
40623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 160
40633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 0, 5,
40643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 161
40653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 1, 5,
40663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 162
40673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 163
40693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 2, 5,
40703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 164
40713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    4, 0, 2,
40723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    5, 7,  // 165
40733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 166
40753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    X, _, _,
40763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    _, _,  // 167
40773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    3, 3, 5,
40783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    7, _,  // 168
40793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    4, 0, 3,
40803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    5, 7,  // 169
40813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    4, 1, 3,
40823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    5, 7  // 170
4083c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com};
4084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#undef _
4085c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#undef X
4086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4087c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Takes a word of mark bits.  Returns the number of objects that start in the
4089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// range.  Puts the offsets of the words in the supplied array.
4090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts) {
4091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int objects = 0;
4092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int offset = 0;
4093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // No consecutive 1 bits.
4095e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((mark_bits & 0x180) != 0x180);
4096e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((mark_bits & 0x18000) != 0x18000);
4097e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((mark_bits & 0x1800000) != 0x1800000);
4098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (mark_bits != 0) {
4100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    int byte = (mark_bits & 0xff);
4101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    mark_bits >>= 8;
4102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (byte != 0) {
4103e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(byte < kStartTableLines);  // No consecutive 1 bits.
4104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      char* table = kStartTable + byte * kStartTableEntriesPerLine;
4105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int objects_in_these_8_words = table[0];
4106e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(objects_in_these_8_words != kStartTableInvalidLine);
4107e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(objects_in_these_8_words < kStartTableEntriesPerLine);
4108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      for (int i = 0; i < objects_in_these_8_words; i++) {
4109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        starts[objects++] = offset + table[1 + i];
4110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
411143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
4112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    offset += 8;
411343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return objects;
411543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
411643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
411743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
411870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgint MarkCompactCollector::SweepInParallel(PagedSpace* space,
411970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org                                          int required_freed_bytes) {
412070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int max_freed = 0;
412170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int max_freed_overall = 0;
41227c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  PageIterator it(space);
4123e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  while (it.has_next()) {
4124e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org    Page* p = it.next();
41257c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    max_freed = SweepInParallel(p, space);
4126e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(max_freed >= 0);
41277c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    if (required_freed_bytes > 0 && max_freed >= required_freed_bytes) {
41287c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org      return max_freed;
4129e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org    }
41307c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    max_freed_overall = Max(max_freed, max_freed_overall);
41313484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    if (p == space->end_of_unswept_pages()) break;
4132e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  }
413370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  return max_freed_overall;
4134e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org}
4135e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
4136e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
41377c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.orgint MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) {
41387c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  int max_freed = 0;
41397c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  if (page->TryParallelSweeping()) {
41407c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    FreeList* free_list = space == heap()->old_pointer_space()
41417c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org                              ? free_list_old_pointer_space_.get()
41427c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org                              : free_list_old_data_space_.get();
41437c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    FreeList private_free_list(space);
4144a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
4145a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                      IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
41467c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org    free_list->Concatenate(&private_free_list);
41477c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  }
41487c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org  return max_freed;
41497c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org}
41507c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org
41517c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org
41521b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgvoid MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
4153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  space->ClearStats();
4154cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager
41553484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  // We defensively initialize end_of_unswept_pages_ here with the first page
41563484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  // of the pages list.
41573484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  space->set_end_of_unswept_pages(space->FirstPage());
41583484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
4159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PageIterator it(space);
41602bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
41611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  int pages_swept = 0;
4162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool unused_page_present = false;
4163750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  bool parallel_sweeping_active = false;
4164c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
4165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (it.has_next()) {
4166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Page* p = it.next();
4167e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE);
41686e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
4169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Clear sweeping flags indicating that marking bits are still intact.
4170a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    p->ClearWasSwept();
4171cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager
41723484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) ||
41733484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        p->IsEvacuationCandidate()) {
4174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Will be processed in EvacuateNewSpaceAndCandidates.
4175e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(evacuation_candidates_.length() > 0);
4176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      continue;
4177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
4178cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager
4179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // One unused page is kept, all further are released before sweeping them.
4180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (p->LiveBytes() == 0) {
4181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (unused_page_present) {
4182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (FLAG_gc_verbose) {
4183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          PrintF("Sweeping 0x%" V8PRIxPTR " released page.\n",
4184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 reinterpret_cast<intptr_t>(p));
4185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
41862efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        // Adjust unswept free bytes because releasing a page expects said
41872efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        // counter to be accurate for unswept pages.
41882efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org        space->IncreaseUnsweptFreeBytes(p);
41893484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org        space->ReleasePage(p);
4190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        continue;
4191cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager      }
4192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      unused_page_present = true;
419343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
4194cbaa060d2827a6c7aab497845a1fe6ae6f2dfab4mads.s.ager
4195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    switch (sweeper) {
4196a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case CONCURRENT_SWEEPING:
4197a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case PARALLEL_SWEEPING:
4198474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        if (!parallel_sweeping_active) {
4199474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          if (FLAG_gc_verbose) {
4200a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            PrintF("Sweeping 0x%" V8PRIxPTR ".\n",
4201474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                   reinterpret_cast<intptr_t>(p));
4202474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          }
4203a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org          Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
4204a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                IGNORE_FREE_SPACE>(space, NULL, p, NULL);
4205474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          pages_swept++;
4206474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          parallel_sweeping_active = true;
4207474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        } else {
4208474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          if (FLAG_gc_verbose) {
4209a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n",
4210474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                   reinterpret_cast<intptr_t>(p));
4211474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          }
4212474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING);
4213474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          space->IncreaseUnsweptFreeBytes(p);
4214474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        }
4215474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        space->set_end_of_unswept_pages(p);
4216474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org        break;
4217a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      case SEQUENTIAL_SWEEPING: {
42181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        if (FLAG_gc_verbose) {
4219a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org          PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p));
42201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        }
4221f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        if (space->identity() == CODE_SPACE && FLAG_zap_code_space) {
4222a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org          Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
4223a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                ZAP_FREE_SPACE>(space, NULL, p, NULL);
4224f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        } else if (space->identity() == CODE_SPACE) {
4225a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org          Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
4226a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                IGNORE_FREE_SPACE>(space, NULL, p, NULL);
4227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        } else {
4228a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org          Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
4229a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                IGNORE_FREE_SPACE>(space, NULL, p, NULL);
4230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
42311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        pages_swept++;
4232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        break;
4233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
42343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      default: { UNREACHABLE(); }
4235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
423643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
423743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  if (FLAG_gc_verbose) {
42391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    PrintF("SweepSpace: %s (%d pages swept)\n",
42403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org           AllocationSpaceName(space->identity()), pages_swept);
42411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
42421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
4243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Give pages that are queued to be freed back to the OS.
4244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap()->FreeQueuedChunks();
424543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
424643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
424743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4248474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgstatic bool ShouldStartSweeperThreads(MarkCompactCollector::SweeperType type) {
4249a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return type == MarkCompactCollector::PARALLEL_SWEEPING ||
4250a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org         type == MarkCompactCollector::CONCURRENT_SWEEPING;
4251474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
4252474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
4253474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
4254474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgstatic bool ShouldWaitForSweeperThreads(
4255474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    MarkCompactCollector::SweeperType type) {
4256a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return type == MarkCompactCollector::PARALLEL_SWEEPING;
4257474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org}
4258474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
4259474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
4260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::SweepSpaces() {
4261474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_SWEEP);
42625c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  double start_time = 0.0;
42635c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  if (FLAG_print_cumulative_gc_stat) {
42645c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    start_time = base::OS::TimeCurrentMillis();
42655c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  }
42665c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org
426743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
4268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  state_ = SWEEP_SPACES;
426943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
4270a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  SweeperType how_to_sweep = CONCURRENT_SWEEPING;
4271a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_SWEEPING;
4272a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_SWEEPING;
42736e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
42743484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  MoveEvacuationCandidatesToEndOfPagesList();
42756e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
4276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Noncompacting collections simply sweep the spaces to clear the mark
4277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // bits and free the nonlive blocks (for old and map spaces).  We sweep
4278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the map space last because freeing non-live maps overwrites them and
4279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the other spaces rely on possibly non-live maps to get the sizes for
4280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // non-live objects.
42813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
42823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope sweep_scope(heap()->tracer(),
4283474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                GCTracer::Scope::MC_SWEEP_OLDSPACE);
42843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    {
42853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      SequentialSweepingScope scope(this);
4286763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      SweepSpace(heap()->old_pointer_space(), how_to_sweep);
4287763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      SweepSpace(heap()->old_data_space(), how_to_sweep);
4288763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    }
428943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4290474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (ShouldStartSweeperThreads(how_to_sweep)) {
4291763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org      StartSweeperThreads();
4292763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    }
42932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4294474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (ShouldWaitForSweeperThreads(how_to_sweep)) {
4295d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org      EnsureSweepingCompleted();
4296763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org    }
42977c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
4298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RemoveDeadInvalidatedCode();
429943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
43013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope sweep_scope(heap()->tracer(),
4302474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                GCTracer::Scope::MC_SWEEP_CODE);
4303a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING);
4304248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  }
4305248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
43063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
43073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope sweep_scope(heap()->tracer(),
4308474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                GCTracer::Scope::MC_SWEEP_CELL);
4309a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING);
4310a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    SweepSpace(heap()->property_cell_space(), SEQUENTIAL_SWEEPING);
4311248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  }
431243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  EvacuateNewSpaceAndCandidates();
431443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // ClearNonLiveTransitions depends on precise sweeping of map space to
4316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // detect whether unmarked map became dead in this collection or in one
4317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // of the previous ones.
43183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  {
43193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    GCTracer::Scope sweep_scope(heap()->tracer(),
4320474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org                                GCTracer::Scope::MC_SWEEP_MAP);
4321a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    SweepSpace(heap()->map_space(), SEQUENTIAL_SWEEPING);
4322248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  }
432343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Deallocate unmarked objects and clear marked bits for marked objects.
4325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  heap_->lo_space()->FreeUnmarkedObjects();
43262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
43276e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  // Deallocate evacuated candidate pages.
43286e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  ReleaseEvacuationCandidates();
43295c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org
43305c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  if (FLAG_print_cumulative_gc_stat) {
43315c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    heap_->tracer()->AddSweepingTime(base::OS::TimeCurrentMillis() -
43325c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org                                     start_time);
43335c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  }
433443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
433543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
433643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4337f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid MarkCompactCollector::ParallelSweepSpaceComplete(PagedSpace* space) {
4338f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  PageIterator it(space);
4339f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  while (it.has_next()) {
4340f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    Page* p = it.next();
4341474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (p->parallel_sweeping() == MemoryChunk::SWEEPING_FINALIZE) {
4342474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE);
4343a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      p->SetWasSwept();
4344f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
4345e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE);
4346f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
4347f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
4348f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
4349f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
4350f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid MarkCompactCollector::ParallelSweepSpacesComplete() {
4351f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ParallelSweepSpaceComplete(heap()->old_pointer_space());
4352f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ParallelSweepSpaceComplete(heap()->old_data_space());
4353f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
4354f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
4355f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
4356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::EnableCodeFlushing(bool enable) {
43578d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (isolate()->debug()->is_loaded() ||
4358876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      isolate()->debug()->has_break_points()) {
4359e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org    enable = false;
4360e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org  }
4361e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
4362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (enable) {
4363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (code_flusher_ != NULL) return;
4364876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    code_flusher_ = new CodeFlusher(isolate());
4365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else {
4366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (code_flusher_ == NULL) return;
4367e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    code_flusher_->EvictAllCandidates();
4368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    delete code_flusher_;
4369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    code_flusher_ = NULL;
437043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
43714e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
43724e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  if (FLAG_trace_code_flushing) {
43734e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    PrintF("[code-flushing is now %s]\n", enable ? "on" : "off");
43744e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
437543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
437643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
437743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// TODO(1466) ReportDeleteIfNeeded is not called currently.
4379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Our profiling tools do not expect intersections between
4380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// code objects. We should either reenable it or change our tools.
4381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj,
4382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                Isolate* isolate) {
4383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (obj->IsCode()) {
4384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    PROFILE(isolate, CodeDeleteEvent(obj->address()));
4385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
438643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
438743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
438843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgIsolate* MarkCompactCollector::isolate() const { return heap_->isolate(); }
4390876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
4391876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
4392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::Initialize() {
4393b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  MarkCompactMarkingVisitor::Initialize();
4394b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org  IncrementalMarking::Initialize();
4395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
439643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
439743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool SlotsBuffer::IsTypedSlot(ObjectSlot slot) {
4399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return reinterpret_cast<uintptr_t>(slot) < NUMBER_OF_SLOT_TYPES;
4400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
440143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
440243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool SlotsBuffer::AddTo(SlotsBufferAllocator* allocator,
44043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                        SlotsBuffer** buffer_address, SlotType type,
44053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                        Address addr, AdditionMode mode) {
4406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SlotsBuffer* buffer = *buffer_address;
4407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (buffer == NULL || !buffer->HasSpaceForTypedSlot()) {
4408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (mode == FAIL_ON_OVERFLOW && ChainLengthThresholdReached(buffer)) {
4409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      allocator->DeallocateChain(buffer_address);
4410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return false;
441130ce411529579186181838984710b0b0980857aaricow@chromium.org    }
4412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    buffer = allocator->AllocateBuffer(buffer);
4413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    *buffer_address = buffer;
44149258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  }
4415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(buffer->HasSpaceForTypedSlot());
4416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  buffer->Add(reinterpret_cast<ObjectSlot>(type));
4417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  buffer->Add(reinterpret_cast<ObjectSlot>(addr));
4418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return true;
4419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
442043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44219258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
4422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) {
4423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (RelocInfo::IsCodeTarget(rmode)) {
4424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return SlotsBuffer::CODE_TARGET_SLOT;
4425b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  } else if (RelocInfo::IsEmbeddedObject(rmode)) {
4426b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    return SlotsBuffer::EMBEDDED_OBJECT_SLOT;
4427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (RelocInfo::IsDebugBreakSlot(rmode)) {
4428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return SlotsBuffer::DEBUG_TARGET_SLOT;
4429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  } else if (RelocInfo::IsJSReturn(rmode)) {
4430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return SlotsBuffer::JS_RETURN_SLOT;
4431b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
4432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  UNREACHABLE();
4433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return SlotsBuffer::NUMBER_OF_SLOT_TYPES;
44349258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
44359258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
44369258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
4437b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgvoid MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) {
4438b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target));
4439bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  RelocInfo::Mode rmode = rinfo->rmode();
4440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (target_page->IsEvacuationCandidate() &&
4441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      (rinfo->host() == NULL ||
4442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com       !ShouldSkipEvacuationSlotRecording(rinfo->host()))) {
4443bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    bool success;
4444bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    if (RelocInfo::IsEmbeddedObject(rmode) && rinfo->IsInConstantPool()) {
4445bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org      // This doesn't need to be typed since it is just a normal heap pointer.
4446bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org      Object** target_pointer =
4447bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org          reinterpret_cast<Object**>(rinfo->constant_pool_entry_address());
44483e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      success = SlotsBuffer::AddTo(
44493e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          &slots_buffer_allocator_, target_page->slots_buffer_address(),
44503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          target_pointer, SlotsBuffer::FAIL_ON_OVERFLOW);
4451bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    } else if (RelocInfo::IsCodeTarget(rmode) && rinfo->IsInConstantPool()) {
44523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      success = SlotsBuffer::AddTo(
44533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          &slots_buffer_allocator_, target_page->slots_buffer_address(),
44543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          SlotsBuffer::CODE_ENTRY_SLOT, rinfo->constant_pool_entry_address(),
44553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          SlotsBuffer::FAIL_ON_OVERFLOW);
4456bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    } else {
44573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      success = SlotsBuffer::AddTo(
44583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          &slots_buffer_allocator_, target_page->slots_buffer_address(),
44593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org          SlotTypeForRMode(rmode), rinfo->pc(), SlotsBuffer::FAIL_ON_OVERFLOW);
4460bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    }
4461bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org    if (!success) {
4462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      EvictEvacuationCandidate(target_page);
4463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
4464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
44659258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
44669258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
44679258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
4468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) {
4469b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target));
4470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (target_page->IsEvacuationCandidate() &&
4471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) {
4472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!SlotsBuffer::AddTo(&slots_buffer_allocator_,
4473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            target_page->slots_buffer_address(),
44743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                            SlotsBuffer::CODE_ENTRY_SLOT, slot,
4475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            SlotsBuffer::FAIL_ON_OVERFLOW)) {
4476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      EvictEvacuationCandidate(target_page);
4477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
4478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
44799258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org}
44809258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
44819258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
448233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgvoid MarkCompactCollector::RecordCodeTargetPatch(Address pc, Code* target) {
4483e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(heap()->gc_state() == Heap::MARK_COMPACT);
448433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  if (is_compacting()) {
44853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    Code* host =
44863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        isolate()->inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer(
44873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org            pc);
448833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    MarkBit mark_bit = Marking::MarkBitFrom(host);
448933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    if (Marking::IsBlack(mark_bit)) {
449033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host);
449133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org      RecordRelocSlot(&rinfo, target);
449233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    }
449333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  }
449433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org}
449533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
449633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
4497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic inline SlotsBuffer::SlotType DecodeSlotType(
4498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    SlotsBuffer::ObjectSlot slot) {
4499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return static_cast<SlotsBuffer::SlotType>(reinterpret_cast<intptr_t>(slot));
4500defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org}
4501defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
4502defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org
4503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid SlotsBuffer::UpdateSlots(Heap* heap) {
4504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PointersUpdatingVisitor v(heap);
450543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) {
4507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ObjectSlot slot = slots_[slot_idx];
4508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!IsTypedSlot(slot)) {
4509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      PointersUpdatingVisitor::UpdateSlot(heap, slot);
4510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
4511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ++slot_idx;
4512e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(slot_idx < idx_);
45133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      UpdateSlot(heap->isolate(), &v, DecodeSlotType(slot),
4514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                 reinterpret_cast<Address>(slots_[slot_idx]));
4515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
451643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
451743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
451843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
451943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid SlotsBuffer::UpdateSlotsWithFilter(Heap* heap) {
4521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  PointersUpdatingVisitor v(heap);
4522b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) {
4524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ObjectSlot slot = slots_[slot_idx];
4525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (!IsTypedSlot(slot)) {
4526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (!IsOnInvalidatedCodeObject(reinterpret_cast<Address>(slot))) {
4527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        PointersUpdatingVisitor::UpdateSlot(heap, slot);
4528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
4529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
4530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ++slot_idx;
4531e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(slot_idx < idx_);
4532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Address pc = reinterpret_cast<Address>(slots_[slot_idx]);
4533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (!IsOnInvalidatedCodeObject(pc)) {
45343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        UpdateSlot(heap->isolate(), &v, DecodeSlotType(slot),
4535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   reinterpret_cast<Address>(slots_[slot_idx]));
4536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
4537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
4538ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
4539ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
4540ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
4541ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
4542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comSlotsBuffer* SlotsBufferAllocator::AllocateBuffer(SlotsBuffer* next_buffer) {
4543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return new SlotsBuffer(next_buffer);
4544b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
4545b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4546ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
4547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid SlotsBufferAllocator::DeallocateBuffer(SlotsBuffer* buffer) {
4548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  delete buffer;
45494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
45504a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
45514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid SlotsBufferAllocator::DeallocateChain(SlotsBuffer** buffer_address) {
4553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SlotsBuffer* buffer = *buffer_address;
4554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (buffer != NULL) {
4555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    SlotsBuffer* next_buffer = buffer->next();
4556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    DeallocateBuffer(buffer);
4557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    buffer = next_buffer;
4558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
4559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  *buffer_address = NULL;
4560ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org}
45613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}
45623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org}  // namespace v8::internal
4563