heap.cc revision bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8
1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/heap.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/accessors.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/api.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopeinfo.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/once.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/utils/random-number-generator.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bootstrapper.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compilation-cache.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/conversions.h"
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h"
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h"
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h"
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/array-buffer-tracker.h"
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/gc-idle-time-handler.h"
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/gc-tracer.h"
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/incremental-marking.h"
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/mark-compact-inl.h"
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/mark-compact.h"
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/memory-reducer.h"
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/object-stats.h"
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/objects-visiting-inl.h"
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/objects-visiting.h"
30109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/heap/remembered-set.h"
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/scavenge-job.h"
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/heap/scavenger-inl.h"
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/store-buffer.h"
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/interpreter/interpreter.h"
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/profiler/cpu-profiler.h"
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/regexp/jsregexp.h"
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/runtime-profiler.h"
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/snapshot/natives.h"
393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#include "src/snapshot/serializer-common.h"
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/snapshot/snapshot.h"
41109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/tracing/trace-event.h"
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/type-feedback-vector.h"
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h"
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/v8.h"
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8threads.h"
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/vm-state-inl.h"
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct Heap::StrongRootsList {
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object** start;
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object** end;
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* next;
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
58109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass IdleScavengeObserver : public AllocationObserver {
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IdleScavengeObserver(Heap& heap, intptr_t step_size)
61109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : AllocationObserver(step_size), heap_(heap) {}
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Step(int bytes_allocated, Address, size_t) override {
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    heap_.ScheduleIdleScavengeIfNeeded(bytes_allocated);
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Heap& heap_;
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::Heap()
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : amount_of_external_allocated_memory_(0),
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      amount_of_external_allocated_memory_at_last_global_gc_(0),
74bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate_(nullptr),
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code_range_size_(0),
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // semispace_size_ should be a power of 2 and old_generation_size_ should
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // be a multiple of Page::kPageSize.
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_semi_space_size_(8 * (kPointerSize / 4) * MB),
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      initial_semispace_size_(Page::kPageSize),
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_old_generation_size_(700ul * (kPointerSize / 4) * MB),
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      initial_old_generation_size_(max_old_generation_size_ /
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   kInitalOldGenerationLimitFactor),
83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      old_generation_size_configured_(false),
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_executable_size_(256ul * (kPointerSize / 4) * MB),
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Variables set based on semispace_size_ and old_generation_size_ in
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // ConfigureHeap.
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Will be 4 * reserved_semispace_size_ to ensure that young
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // generation can be aligned to its size.
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      maximum_committed_(0),
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      survived_since_last_expansion_(0),
91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      survived_last_scavenge_(0),
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      always_allocate_scope_count_(0),
933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      memory_pressure_level_(MemoryPressureLevel::kNone),
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      contexts_disposed_(0),
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      number_of_disposed_maps_(0),
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      global_ic_age_(0),
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new_space_(this),
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      old_space_(NULL),
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code_space_(NULL),
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      map_space_(NULL),
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      lo_space_(NULL),
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_state_(NOT_IN_GC),
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_post_processing_depth_(0),
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      allocations_count_(0),
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      raw_allocations_hash_(0),
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ms_count_(0),
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_count_(0),
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      remembered_unmapped_pages_index_(0),
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      allocation_timeout_(0),
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      old_generation_allocation_limit_(initial_old_generation_size_),
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      old_gen_exhausted_(false),
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      optimize_for_memory_usage_(false),
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      inline_allocation_disabled_(false),
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      total_regexp_code_generated_(0),
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer_(nullptr),
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      high_survival_rate_period_length_(0),
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      promoted_objects_size_(0),
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      promotion_ratio_(0),
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      semi_space_copied_object_size_(0),
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      previous_semi_space_copied_object_size_(0),
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      semi_space_copied_rate_(0),
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      nodes_died_in_new_space_(0),
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      nodes_copied_in_new_space_(0),
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      nodes_promoted_(0),
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      maximum_size_scavenges_(0),
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_gc_pause_(0.0),
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      total_gc_time_ms_(0.0),
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_alive_after_gc_(0),
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      min_in_mutator_(kMaxInt),
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      marking_time_(0.0),
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      sweeping_time_(0.0),
134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_idle_notification_time_(0.0),
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_gc_time_(0.0),
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scavenge_collector_(nullptr),
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      mark_compact_collector_(nullptr),
138bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      memory_allocator_(nullptr),
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      store_buffer_(this),
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      incremental_marking_(nullptr),
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      gc_idle_time_handler_(nullptr),
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      memory_reducer_(nullptr),
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_stats_(nullptr),
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scavenge_job_(nullptr),
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      idle_scavenge_observer_(nullptr),
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      full_codegen_bytes_generated_(0),
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      crankshaft_codegen_bytes_generated_(0),
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new_space_allocation_counter_(0),
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      old_generation_allocation_counter_(0),
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      old_generation_size_at_last_gc_(0),
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gcs_since_last_deopt_(0),
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      global_pretenuring_feedback_(nullptr),
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ring_buffer_full_(false),
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ring_buffer_end_(0),
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      promotion_queue_(this),
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      configured_(false),
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_gc_flags_(Heap::kNoGCFlags),
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_gc_callback_flags_(GCCallbackFlags::kNoGCCallbackFlags),
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      external_string_table_(this),
160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      gc_callbacks_depth_(0),
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      deserialization_complete_(false),
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      strong_roots_list_(NULL),
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array_buffer_tracker_(NULL),
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      heap_iterator_depth_(0),
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      force_oom_(false) {
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Allow build-time customization of the max semispace size. Building
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// V8 with snapshots and a non-default max semispace size is much
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// easier if you can define it as part of the build environment.
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(V8_MAX_SEMISPACE_SIZE)
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Ensure old_generation_size_ is a multiple of kPageSize.
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((max_old_generation_size_ & (Page::kPageSize - 1)) == 0);
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_native_contexts_list(NULL);
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_allocation_sites_list(Smi::FromInt(0));
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_encountered_weak_collections(Smi::FromInt(0));
180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  set_encountered_weak_cells(Smi::FromInt(0));
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_encountered_transition_arrays(Smi::FromInt(0));
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Put a dummy entry in the remembered pages so we can find the list the
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // minidump even if there are no real unmapped pages.
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RememberUnmappedPage(NULL, false);
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::Capacity() {
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
191bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return new_space_.Capacity() + OldGenerationCapacity();
192bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
193bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
194bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochintptr_t Heap::OldGenerationCapacity() {
195bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (!HasBeenSetUp()) return 0;
196bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
197bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return old_space_->Capacity() + code_space_->Capacity() +
198bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         map_space_->Capacity() + lo_space_->SizeOfObjects();
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochintptr_t Heap::CommittedOldGenerationMemory() {
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!HasBeenSetUp()) return 0;
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return old_space_->CommittedMemory() + code_space_->CommittedMemory() +
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         map_space_->CommittedMemory() + lo_space_->Size();
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::CommittedMemory() {
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new_space_.CommittedMemory() + CommittedOldGenerationMemory();
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t Heap::CommittedPhysicalMemory() {
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_space_.CommittedPhysicalMemory() +
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         old_space_->CommittedPhysicalMemory() +
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         code_space_->CommittedPhysicalMemory() +
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         map_space_->CommittedPhysicalMemory() +
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         lo_space_->CommittedPhysicalMemory();
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::CommittedMemoryExecutable() {
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
231bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return memory_allocator()->SizeExecutable();
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateMaximumCommitted() {
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return;
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t current_committed_memory = CommittedMemory();
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (current_committed_memory > maximum_committed_) {
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maximum_committed_ = current_committed_memory;
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::Available() {
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return 0;
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t total = 0;
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllSpaces spaces(this);
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    total += space->Available();
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return total;
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::HasBeenSetUp() {
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return old_space_ != NULL && code_space_ != NULL && map_space_ != NULL &&
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         lo_space_ != NULL;
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochGarbageCollector Heap::SelectGarbageCollector(AllocationSpace space,
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              const char** reason) {
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Is global GC requested?
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (space != NEW_SPACE) {
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->gc_compactor_caused_by_request()->Increment();
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reason = "GC in old space requested";
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MARK_COMPACTOR;
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) {
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reason = "GC in old space forced by flags";
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MARK_COMPACTOR;
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Is enough data promoted to justify a global GC?
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (OldGenerationAllocationLimitReached()) {
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->gc_compactor_caused_by_promoted_data()->Increment();
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reason = "promotion limit reached";
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MARK_COMPACTOR;
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Have allocation in OLD and LO failed?
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (old_gen_exhausted_) {
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ->gc_compactor_caused_by_oldspace_exhaustion()
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ->Increment();
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reason = "old generations exhausted";
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MARK_COMPACTOR;
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Is there enough space left in OLD to guarantee that a scavenge can
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // succeed?
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Note that MemoryAllocator->MaxAvailable() undercounts the memory available
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for object promotion. It counts only the bytes that the memory
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // allocator has not yet allocated from the OS and assigned to any space,
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and does not count available bytes already in the old space or code
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // space.  Undercounting is safe---we may get an unrequested full GC when
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // a scavenge would have succeeded.
302bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (memory_allocator()->MaxAvailable() <= new_space_.Size()) {
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ->gc_compactor_caused_by_oldspace_exhaustion()
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ->Increment();
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reason = "scavenge might not succeed";
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MARK_COMPACTOR;
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Default
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *reason = NULL;
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return SCAVENGER;
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(1238405): Combine the infrastructure for --heap-stats and
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --log-gc to avoid the complicated preprocessor and flag testing.
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportStatisticsBeforeGC() {
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Heap::ReportHeapStatistics will also log NewSpace statistics when
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// compiled --log-gc is set.  The following logic is used to avoid
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// double logging.
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_heap_stats || FLAG_log_gc) new_space_.CollectStatistics();
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_heap_stats) {
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ReportHeapStatistics("Before GC");
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (FLAG_log_gc) {
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    new_space_.ReportStatistics();
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_heap_stats || FLAG_log_gc) new_space_.ClearHistograms();
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_log_gc) {
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    new_space_.CollectStatistics();
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    new_space_.ReportStatistics();
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    new_space_.ClearHistograms();
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::PrintShortHeapStatistics() {
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!FLAG_trace_gc_verbose) return;
342bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrintIsolate(isolate_, "Memory allocator,   used: %6" V8PRIdPTR
343bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB, available: %6" V8PRIdPTR " KB\n",
344bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch               memory_allocator()->Size() / KB,
345bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch               memory_allocator()->Available() / KB);
346bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrintIsolate(isolate_, "New space,          used: %6" V8PRIdPTR
347bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
348bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", available: %6" V8PRIdPTR
349bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
350bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", committed: %6" V8PRIdPTR " KB\n",
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               new_space_.Size() / KB, new_space_.Available() / KB,
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               new_space_.CommittedMemory() / KB);
353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrintIsolate(isolate_, "Old space,          used: %6" V8PRIdPTR
354bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
355bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", available: %6" V8PRIdPTR
356bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
357bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", committed: %6" V8PRIdPTR " KB\n",
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               old_space_->SizeOfObjects() / KB, old_space_->Available() / KB,
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               old_space_->CommittedMemory() / KB);
360bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrintIsolate(isolate_, "Code space,         used: %6" V8PRIdPTR
361bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
362bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", available: %6" V8PRIdPTR
363bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
364bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", committed: %6" V8PRIdPTR " KB\n",
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               code_space_->SizeOfObjects() / KB, code_space_->Available() / KB,
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               code_space_->CommittedMemory() / KB);
367bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrintIsolate(isolate_, "Map space,          used: %6" V8PRIdPTR
368bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
369bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", available: %6" V8PRIdPTR
370bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
371bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", committed: %6" V8PRIdPTR " KB\n",
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               map_space_->SizeOfObjects() / KB, map_space_->Available() / KB,
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               map_space_->CommittedMemory() / KB);
374bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrintIsolate(isolate_, "Large object space, used: %6" V8PRIdPTR
375bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
376bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", available: %6" V8PRIdPTR
377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", committed: %6" V8PRIdPTR " KB\n",
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               lo_space_->SizeOfObjects() / KB, lo_space_->Available() / KB,
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               lo_space_->CommittedMemory() / KB);
381bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrintIsolate(isolate_, "All spaces,         used: %6" V8PRIdPTR
382bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
383bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", available: %6" V8PRIdPTR
384bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         " KB"
385bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         ", committed: %6" V8PRIdPTR " KB\n",
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               this->SizeOfObjects() / KB, this->Available() / KB,
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               this->CommittedMemory() / KB);
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintIsolate(
389bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      isolate_, "External memory reported: %6" V8PRIdPTR " KB\n",
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<intptr_t>(amount_of_external_allocated_memory_ / KB));
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintIsolate(isolate_, "Total time spent in GC  : %.1f ms\n",
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               total_gc_time_ms_);
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(1238405): Combine the infrastructure for --heap-stats and
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --log-gc to avoid the complicated preprocessor and flag testing.
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportStatisticsAfterGC() {
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Similar to the before GC, we use some complicated logic to ensure that
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NewSpace statistics are logged exactly once when --log-gc is turned on.
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(DEBUG)
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_heap_stats) {
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    new_space_.CollectStatistics();
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ReportHeapStatistics("After GC");
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (FLAG_log_gc) {
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    new_space_.ReportStatistics();
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_log_gc) new_space_.ReportStatistics();
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount);
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       ++i) {
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int count = deferred_counters_[i];
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    deferred_counters_[i] = 0;
414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (count > 0) {
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      count--;
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->CountUsage(static_cast<v8::Isolate::UseCounterFeature>(i));
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::IncrementDeferredCount(v8::Isolate::UseCounterFeature feature) {
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  deferred_counters_[feature]++;
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::GarbageCollectionPrologue() {
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllowHeapAllocation for_the_first_part_of_prologue;
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    gc_count_++;
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_verify_heap) {
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Verify();
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Reset GC statistics.
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  promoted_objects_size_ = 0;
441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  previous_semi_space_copied_object_size_ = semi_space_copied_object_size_;
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  semi_space_copied_object_size_ = 0;
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  nodes_died_in_new_space_ = 0;
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  nodes_copied_in_new_space_ = 0;
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  nodes_promoted_ = 0;
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateMaximumCommitted();
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC);
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_gc_verbose) Print();
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ReportStatisticsBeforeGC();
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (new_space_.IsAtMaximumCapacity()) {
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maximum_size_scavenges_++;
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maximum_size_scavenges_ = 0;
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CheckNewSpaceExpansionCriteria();
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UpdateNewSpaceAllocationCounter();
464109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  store_buffer()->MoveEntriesToRememberedSet();
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::SizeOfObjects() {
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t total = 0;
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllSpaces spaces(this);
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    total += space->SizeOfObjects();
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return total;
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* Heap::GetSpaceName(int idx) {
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (idx) {
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case NEW_SPACE:
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "new_space";
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "old_space";
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MAP_SPACE:
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "map_space";
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CODE_SPACE:
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "code_space";
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case LO_SPACE:
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "large_object_space";
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RepairFreeListsAfterDeserialization() {
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PagedSpaces spaces(this);
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (PagedSpace* space = spaces.next(); space != NULL;
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       space = spaces.next()) {
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    space->RepairFreeListsAfterDeserialization();
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::MergeAllocationSitePretenuringFeedback(
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const HashMap& local_pretenuring_feedback) {
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSite* site = nullptr;
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (HashMap::Entry* local_entry = local_pretenuring_feedback.Start();
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       local_entry != nullptr;
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       local_entry = local_pretenuring_feedback.Next(local_entry)) {
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    site = reinterpret_cast<AllocationSite*>(local_entry->key);
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MapWord map_word = site->map_word();
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (map_word.IsForwardingAddress()) {
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      site = AllocationSite::cast(map_word.ToForwardingAddress());
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // We have not validated the allocation site yet, since we have not
519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // dereferenced the site during collecting information.
520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // This is an inlined check of AllocationMemento::IsValid.
521109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!site->IsAllocationSite() || site->IsZombie()) continue;
522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int value =
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        static_cast<int>(reinterpret_cast<intptr_t>(local_entry->value));
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_GT(value, 0);
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (site->IncrementMementoFoundCount(value)) {
528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      global_pretenuring_feedback_->LookupOrInsert(site,
529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                                   ObjectHash(site->address()));
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Heap::PretenuringScope {
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit PretenuringScope(Heap* heap) : heap_(heap) {
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    heap_->global_pretenuring_feedback_ =
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        new HashMap(HashMap::PointersMatch, kInitialFeedbackCapacity);
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ~PretenuringScope() {
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete heap_->global_pretenuring_feedback_;
544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    heap_->global_pretenuring_feedback_ = nullptr;
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Heap* heap_;
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessPretenuringFeedback() {
553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool trigger_deoptimization = false;
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_allocation_site_pretenuring) {
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int tenure_decisions = 0;
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int dont_tenure_decisions = 0;
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int allocation_mementos_found = 0;
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int allocation_sites = 0;
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int active_allocation_sites = 0;
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationSite* site = nullptr;
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step 1: Digest feedback for recorded allocation sites.
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool maximum_size_scavenge = MaximumSizeScavenge();
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (HashMap::Entry* e = global_pretenuring_feedback_->Start();
566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         e != nullptr; e = global_pretenuring_feedback_->Next(e)) {
567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      allocation_sites++;
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      site = reinterpret_cast<AllocationSite*>(e->key);
569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int found_count = site->memento_found_count();
570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // An entry in the storage does not imply that the count is > 0 because
571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // allocation sites might have been reset due to too many objects dying
572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // in old space.
573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (found_count > 0) {
574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(site->IsAllocationSite());
575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        active_allocation_sites++;
576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        allocation_mementos_found += found_count;
577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (site->DigestPretenuringFeedback(maximum_size_scavenge)) {
578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          trigger_deoptimization = true;
579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (site->GetPretenureMode() == TENURED) {
581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          tenure_decisions++;
582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        } else {
583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          dont_tenure_decisions++;
584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step 2: Deopt maybe tenured allocation sites if necessary.
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool deopt_maybe_tenured = DeoptMaybeTenuredAllocationSites();
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (deopt_maybe_tenured) {
591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Object* list_element = allocation_sites_list();
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      while (list_element->IsAllocationSite()) {
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        site = AllocationSite::cast(list_element);
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(site->IsAllocationSite());
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        allocation_sites++;
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (site->IsMaybeTenure()) {
597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          site->set_deopt_dependent_code(true);
598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          trigger_deoptimization = true;
599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        list_element = site->weak_next();
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (trigger_deoptimization) {
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->stack_guard()->RequestDeoptMarkedAllocationSites();
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_trace_pretenuring_statistics &&
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (allocation_mementos_found > 0 || tenure_decisions > 0 ||
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         dont_tenure_decisions > 0)) {
611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintIsolate(isolate(),
612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   "pretenuring: deopt_maybe_tenured=%d visited_sites=%d "
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   "active_sites=%d "
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   "mementos=%d tenured=%d not_tenured=%d\n",
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   deopt_maybe_tenured ? 1 : 0, allocation_sites,
616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   active_allocation_sites, allocation_mementos_found,
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   tenure_decisions, dont_tenure_decisions);
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::DeoptMarkedAllocationSites() {
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(hpayer): If iterating over the allocation sites list becomes a
625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // performance issue, use a cache data structure in heap instead.
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* list_element = allocation_sites_list();
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (list_element->IsAllocationSite()) {
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationSite* site = AllocationSite::cast(list_element);
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (site->deopt_dependent_code()) {
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      site->dependent_code()->MarkCodeForDeoptimization(
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate_, DependentCode::kAllocationSiteTenuringChangedGroup);
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      site->set_deopt_dependent_code(false);
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    list_element = site->weak_next();
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Deoptimizer::DeoptimizeMarkedCode(isolate_);
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::GarbageCollectionEpilogue() {
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // In release mode, we only zap the from space under heap verification.
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (Heap::ShouldZapGarbage()) {
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ZapFromSpace();
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Verify();
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowHeapAllocation for_the_rest_of_the_epilogue;
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_print_global_handles) isolate_->global_handles()->Print();
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_print_handles) PrintHandles();
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_gc_verbose) Print();
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_code_stats) ReportCodeStatistics("After GC");
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_check_handle_count) CheckHandleCount();
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_deopt_every_n_garbage_collections > 0) {
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(jkummerow/ulan/jarin): This is not safe! We can't assume that
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the topmost optimized frame can be deoptimized safely, because it
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // might not have a lazy bailout point right after its current PC.
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (++gcs_since_last_deopt_ == FLAG_deopt_every_n_garbage_collections) {
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Deoptimizer::DeoptimizeAll(isolate());
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gcs_since_last_deopt_ = 0;
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateMaximumCommitted();
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->alive_after_last_gc()->Set(
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(SizeOfObjects()));
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->string_table_capacity()->Set(
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      string_table()->Capacity());
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->number_of_symbols()->Set(
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      string_table()->NumberOfElements());
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (full_codegen_bytes_generated_ + crankshaft_codegen_bytes_generated_ > 0) {
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->codegen_fraction_crankshaft()->AddSample(
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>((crankshaft_codegen_bytes_generated_ * 100.0) /
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         (crankshaft_codegen_bytes_generated_ +
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          full_codegen_bytes_generated_)));
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (CommittedMemory() > 0) {
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->external_fragmentation_total()->AddSample(
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(100 - (SizeOfObjects() * 100.0) / CommittedMemory()));
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_fraction_new_space()->AddSample(static_cast<int>(
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (new_space()->CommittedMemory() * 100.0) / CommittedMemory()));
694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate_->counters()->heap_fraction_old_space()->AddSample(static_cast<int>(
695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (old_space()->CommittedMemory() * 100.0) / CommittedMemory()));
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_fraction_code_space()->AddSample(
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>((code_space()->CommittedMemory() * 100.0) /
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         CommittedMemory()));
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_fraction_map_space()->AddSample(static_cast<int>(
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (map_space()->CommittedMemory() * 100.0) / CommittedMemory()));
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_fraction_lo_space()->AddSample(static_cast<int>(
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (lo_space()->CommittedMemory() * 100.0) / CommittedMemory()));
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_total_committed()->AddSample(
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(CommittedMemory() / KB));
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_total_used()->AddSample(
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(SizeOfObjects() / KB));
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_map_space_committed()->AddSample(
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(map_space()->CommittedMemory() / KB));
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_code_space_committed()->AddSample(
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(code_space()->CommittedMemory() / KB));
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->heap_sample_maximum_committed()->AddSample(
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(MaximumCommittedMemory() / KB));
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UPDATE_COUNTERS_FOR_SPACE(space)                \
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->space##_bytes_available()->Set( \
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(space()->Available()));          \
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->space##_bytes_committed()->Set( \
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(space()->CommittedMemory()));    \
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->space##_bytes_used()->Set(      \
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(space()->SizeOfObjects()));
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UPDATE_FRAGMENTATION_FOR_SPACE(space)                          \
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (space()->CommittedMemory() > 0) {                                \
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->counters()->external_fragmentation_##space()->AddSample( \
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<int>(100 -                                         \
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         (space()->SizeOfObjects() * 100.0) /          \
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             space()->CommittedMemory()));             \
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(space) \
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_FOR_SPACE(space)                         \
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_FRAGMENTATION_FOR_SPACE(space)
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_FOR_SPACE(new_space)
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(old_space)
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(code_space)
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(map_space)
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE(lo_space)
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef UPDATE_COUNTERS_FOR_SPACE
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef UPDATE_FRAGMENTATION_FOR_SPACE
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ReportStatisticsAfterGC();
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Remember the last top pointer so that we can later find out
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // whether we allocated in new space since the last GC.
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_top_after_last_gc_ = new_space()->top();
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  last_gc_time_ = MonotonicallyIncreasingTimeInMs();
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReduceNewSpaceSize();
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::PreprocessStackTraces() {
758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WeakFixedArray::Iterator iterator(weak_stack_trace_list());
759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* elements;
760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while ((elements = iterator.Next<FixedArray>())) {
761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int j = 1; j < elements->length(); j += 4) {
762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Object* maybe_code = elements->get(j + 2);
763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // If GC happens while adding a stack trace to the weak fixed array,
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // which has been copied into a larger backing store, we may run into
765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // a stack trace that has already been preprocessed. Guard against this.
766bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!maybe_code->IsAbstractCode()) break;
767bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      AbstractCode* abstract_code = AbstractCode::cast(maybe_code);
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int offset = Smi::cast(elements->get(j + 3))->value();
769bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      int pos = abstract_code->SourcePosition(offset);
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      elements->set(j + 2, Smi::FromInt(pos));
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We must not compact the weak fixed list here, as we may be in the middle
774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // of writing to it, when the GC triggered. Instead, we reset the root value.
775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_weak_stack_trace_list(Smi::FromInt(0));
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass GCCallbacksScope {
780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit GCCallbacksScope(Heap* heap) : heap_(heap) {
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    heap_->gc_callbacks_depth_++;
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ~GCCallbacksScope() { heap_->gc_callbacks_depth_--; }
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool CheckReenter() { return heap_->gc_callbacks_depth_ == 1; }
787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Heap* heap_;
790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::HandleGCRequest() {
7943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (HighMemoryPressure()) {
7953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    incremental_marking()->reset_request_type();
7963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CheckMemoryPressure();
7973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (incremental_marking()->request_type() ==
7983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             IncrementalMarking::COMPLETE_MARKING) {
7993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    incremental_marking()->reset_request_type();
800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CollectAllGarbage(current_gc_flags_, "GC interrupt",
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      current_gc_callback_flags_);
8023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (incremental_marking()->request_type() ==
8033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                 IncrementalMarking::FINALIZATION &&
8043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             incremental_marking()->IsMarking() &&
805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             !incremental_marking()->finalize_marking_completed()) {
8063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    incremental_marking()->reset_request_type();
807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FinalizeIncrementalMarking("GC interrupt: finalize incremental marking");
808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ScheduleIdleScavengeIfNeeded(int bytes_allocated) {
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_job_->ScheduleIdleTaskIfNeeded(this, bytes_allocated);
814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::FinalizeIncrementalMarking(const char* gc_reason) {
818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_incremental_marking) {
819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("[IncrementalMarking] (%s).\n", gc_reason);
820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HistogramTimerScope incremental_marking_scope(
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->counters()->gc_incremental_marking_finalize());
824109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE_EVENT0("v8", "V8.GCIncrementalMarkingFinalize");
825bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  TRACE_GC(tracer(), GCTracer::Scope::MC_INCREMENTAL_FINALIZE);
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GCCallbacksScope scope(this);
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (scope.CheckReenter()) {
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllowHeapAllocation allow_allocation;
8313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      TRACE_GC(tracer(), GCTracer::Scope::MC_INCREMENTAL_EXTERNAL_PROLOGUE);
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VMState<EXTERNAL> state(isolate_);
833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HandleScope handle_scope(isolate_);
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CallGCPrologueCallbacks(kGCTypeIncrementalMarking, kNoGCCallbackFlags);
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incremental_marking()->FinalizeIncrementally();
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GCCallbacksScope scope(this);
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (scope.CheckReenter()) {
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllowHeapAllocation allow_allocation;
8423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      TRACE_GC(tracer(), GCTracer::Scope::MC_INCREMENTAL_EXTERNAL_EPILOGUE);
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VMState<EXTERNAL> state(isolate_);
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HandleScope handle_scope(isolate_);
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CallGCEpilogueCallbacks(kGCTypeIncrementalMarking, kNoGCCallbackFlags);
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHistogramTimer* Heap::GCTypeTimer(GarbageCollector collector) {
852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (collector == SCAVENGER) {
853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return isolate_->counters()->gc_scavenger();
854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!incremental_marking()->IsStopped()) {
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (ShouldReduceMemory()) {
857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate_->counters()->gc_finalize_reduce_memory();
858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return isolate_->counters()->gc_finalize();
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return isolate_->counters()->gc_compactor();
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CollectAllGarbage(int flags, const char* gc_reason,
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             const v8::GCCallbackFlags gc_callback_flags) {
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Since we are ignoring the return value, the exact choice of space does
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // not matter, so long as we do not specify NEW_SPACE, which would not
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // cause a full GC.
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(flags);
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CollectGarbage(OLD_SPACE, gc_reason, gc_callback_flags);
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(kNoGCFlags);
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CollectAllAvailableGarbage(const char* gc_reason) {
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Since we are ignoring the return value, the exact choice of space does
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // not matter, so long as we do not specify NEW_SPACE, which would not
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // cause a full GC.
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Major GC would invoke weak handle callbacks on weakly reachable
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // handles, but won't collect weakly reachable objects until next
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // major GC.  Therefore if we collect aggressively and weak handle callback
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // has been invoked, we rerun major GC to release objects which become
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // garbage.
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Note: as weak callbacks can execute arbitrary code, we cannot
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // hope that eventually there will be no weak callbacks invocations.
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Therefore stop recollecting after several attempts.
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (isolate()->concurrent_recompilation_enabled()) {
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The optimizing compiler may be unnecessarily holding on to memory.
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DisallowHeapAllocation no_recursive_gc;
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->optimizing_compile_dispatcher()->Flush();
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate()->ClearSerializerData();
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(kMakeHeapIterableMask | kReduceMemoryFootprintMask);
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->compilation_cache()->Clear();
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kMaxNumberOfAttempts = 7;
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kMinNumberOfAttempts = 2;
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) {
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!CollectGarbage(MARK_COMPACTOR, gc_reason, NULL,
902109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                        v8::kGCCallbackFlagCollectAllAvailableGarbage) &&
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        attempt + 1 >= kMinNumberOfAttempts) {
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(kNoGCFlags);
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_.Shrink();
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UncommitFromSpace();
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ReportExternalMemoryPressure(const char* gc_reason) {
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incremental_marking()->IsStopped()) {
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (incremental_marking()->CanBeActivated()) {
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      StartIncrementalMarking(
917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          i::Heap::kNoGCFlags,
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          kGCCallbackFlagSynchronousPhantomCallbackProcessing, gc_reason);
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CollectAllGarbage(i::Heap::kNoGCFlags, gc_reason,
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        kGCCallbackFlagSynchronousPhantomCallbackProcessing);
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Incremental marking is turned on an has already been started.
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // TODO(mlippautz): Compute the time slice for incremental marking based on
927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // memory pressure.
928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    double deadline = MonotonicallyIncreasingTimeInMs() +
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      FLAG_external_allocation_limit_incremental_time;
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    incremental_marking()->AdvanceIncrementalMarking(
9313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        deadline,
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        IncrementalMarking::StepActions(IncrementalMarking::GC_VIA_STACK_GUARD,
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        IncrementalMarking::FORCE_MARKING,
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        IncrementalMarking::FORCE_COMPLETION));
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnsureFillerObjectAtTop() {
9403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // There may be an allocation memento behind objects in new space. Upon
9413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // evacuation of a non-full new space (or if we are on the last page) there
9423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // may be uninitialized memory behind top. We fill the remainder of the page
9433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // with a filler.
9443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Address to_top = new_space_.top();
945bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Page* page = Page::FromAddress(to_top - kPointerSize);
9463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (page->Contains(to_top)) {
9473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    int remaining_in_page = static_cast<int>(page->area_end() - to_top);
9483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CreateFillerObjectAt(to_top, remaining_in_page, ClearRecordedSlots::kNo);
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason,
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          const char* collector_reason,
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          const v8::GCCallbackFlags gc_callback_flags) {
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The VM is in the GC state until exiting this function.
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VMState<GC> state(isolate_);
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Reset the allocation timeout to the GC interval, but make sure to
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // allow at least a few allocations after a collection. The reason
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for this is that we have a lot of allocation sequences and we
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // assume that a garbage collection will allow the subsequent
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // allocation attempts to go through.
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  allocation_timeout_ = Max(6, FLAG_gc_interval);
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureFillerObjectAtTop();
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (collector == SCAVENGER && !incremental_marking()->IsStopped()) {
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_trace_incremental_marking) {
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF("[IncrementalMarking] Scavenge during marking.\n");
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (collector == MARK_COMPACTOR && !ShouldFinalizeIncrementalMarking() &&
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      !ShouldAbortIncrementalMarking() && !incremental_marking()->IsStopped() &&
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      !incremental_marking()->should_hurry() && FLAG_incremental_marking &&
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      OldGenerationAllocationLimitReached()) {
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!incremental_marking()->IsComplete() &&
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !mark_compact_collector()->marking_deque_.IsEmpty() &&
982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !FLAG_gc_global) {
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_trace_incremental_marking) {
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF("[IncrementalMarking] Delaying MarkSweep.\n");
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      collector = SCAVENGER;
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      collector_reason = "incremental marking delaying mark-sweep";
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool next_gc_likely_to_collect_more = false;
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t committed_memory_before = 0;
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (collector == MARK_COMPACTOR) {
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    committed_memory_before = CommittedOldGenerationMemory();
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    tracer()->Start(collector, gc_reason, collector_reason);
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(AllowHeapAllocation::IsAllowed());
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DisallowHeapAllocation no_allocation_during_gc;
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GarbageCollectionPrologue();
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
1005109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HistogramTimer* gc_type_timer = GCTypeTimer(collector);
1006109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      HistogramTimerScope histogram_timer_scope(gc_type_timer);
1007109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      TRACE_EVENT0("v8", gc_type_timer->name());
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_gc_likely_to_collect_more =
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          PerformGarbageCollection(collector, gc_callback_flags);
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GarbageCollectionEpilogue();
1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (collector == MARK_COMPACTOR && FLAG_track_detached_contexts) {
1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->CheckDetachedContextsAfterGC();
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (collector == MARK_COMPACTOR) {
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t committed_memory_after = CommittedOldGenerationMemory();
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      intptr_t used_memory_after = PromotedSpaceSizeOfObjects();
1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MemoryReducer::Event event;
1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      event.type = MemoryReducer::kMarkCompact;
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      event.time_ms = MonotonicallyIncreasingTimeInMs();
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Trigger one more GC if
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // - this GC decreased committed memory,
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // - there is high fragmentation,
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // - there are live detached contexts.
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      event.next_gc_likely_to_collect_more =
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          (committed_memory_before - committed_memory_after) > MB ||
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          HasHighFragmentation(used_memory_after, committed_memory_after) ||
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          (detached_contexts()->length() > 0);
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (deserialization_complete_) {
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        memory_reducer_->NotifyMarkCompact(event);
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
10353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      memory_pressure_level_.SetValue(MemoryPressureLevel::kNone);
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    tracer()->Stop(collector);
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (collector == MARK_COMPACTOR &&
1042109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      (gc_callback_flags & (kGCCallbackFlagForced |
1043109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                            kGCCallbackFlagCollectAllAvailableGarbage)) != 0) {
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->CountUsage(v8::Isolate::kForcedGC);
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Start incremental marking for the next cycle. The heap snapshot
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generator needs incremental marking to stay off after it aborted.
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!ShouldAbortIncrementalMarking() && incremental_marking()->IsStopped() &&
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) {
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StartIncrementalMarking(kNoGCFlags, kNoGCCallbackFlags, "GC epilogue");
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return next_gc_likely_to_collect_more;
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint Heap::NotifyContextDisposed(bool dependant_context) {
1059958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!dependant_context) {
1060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    tracer()->ResetSurvivalEvents();
1061958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    old_generation_size_configured_ = false;
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MemoryReducer::Event event;
1063109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    event.type = MemoryReducer::kPossibleGarbage;
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    event.time_ms = MonotonicallyIncreasingTimeInMs();
1065109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    memory_reducer_->NotifyPossibleGarbage(event);
1066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (isolate()->concurrent_recompilation_enabled()) {
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Flush the queued recompilation tasks.
1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->optimizing_compile_dispatcher()->Flush();
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AgeInlineCaches();
1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  number_of_disposed_maps_ = retained_maps()->Length();
1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer()->AddContextDisposalTime(MonotonicallyIncreasingTimeInMs());
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ++contexts_disposed_;
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::StartIncrementalMarking(int gc_flags,
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   const GCCallbackFlags gc_callback_flags,
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   const char* reason) {
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(incremental_marking()->IsStopped());
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_current_gc_flags(gc_flags);
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  current_gc_callback_flags_ = gc_callback_flags;
1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incremental_marking()->Start(reason);
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::StartIdleIncrementalMarking() {
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  gc_idle_time_handler_->ResetNoProgressCounter();
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StartIncrementalMarking(kReduceMemoryFootprintMask, kNoGCCallbackFlags,
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          "idle");
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MoveElements(FixedArray* array, int dst_index, int src_index,
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        int len) {
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (len == 0) return;
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(array->map() != fixed_cow_array_map());
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** dst_objects = array->data_start() + dst_index;
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize);
1102bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(this, array, dst_index, len);
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper class for verifying the string table.
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StringTableVerifier : public ObjectVisitor {
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Visit all HeapObject pointers in [start, end).
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Object** p = start; p < end; p++) {
1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if ((*p)->IsHeapObject()) {
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Check that the string is actually internalized.
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK((*p)->IsTheHole() || (*p)->IsUndefined() ||
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (*p)->IsInternalizedString());
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void VerifyStringTable(Heap* heap) {
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StringTableVerifier verifier;
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap->string_table()->IterateElements(&verifier);
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // VERIFY_HEAP
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Heap::ReserveSpace(Reservation* reservations) {
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool gc_performed = true;
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int counter = 0;
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kThreshold = 20;
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (gc_performed && counter++ < kThreshold) {
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    gc_performed = false;
11363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (int space = NEW_SPACE; space < SerializerDeserializer::kNumberOfSpaces;
11373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         space++) {
1138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Reservation* reservation = &reservations[space];
1139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK_LE(1, reservation->length());
1140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (reservation->at(0).size == 0) continue;
1141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      bool perform_gc = false;
1142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (space == LO_SPACE) {
1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK_EQ(1, reservation->length());
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        perform_gc = !CanExpandOldGeneration(reservation->at(0).size);
1145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        for (auto& chunk : *reservation) {
1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          AllocationResult allocation;
1148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          int size = chunk.size;
1149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          DCHECK_LE(size, MemoryAllocator::PageAreaSize(
1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              static_cast<AllocationSpace>(space)));
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (space == NEW_SPACE) {
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            allocation = new_space()->AllocateRawUnaligned(size);
1153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          } else {
11543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            // The deserializer will update the skip list.
11553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            allocation = paged_space(space)->AllocateRawUnaligned(
11563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                size, PagedSpace::IGNORE_SKIP_LIST);
1157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          }
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          HeapObject* free_space = nullptr;
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (allocation.To(&free_space)) {
1160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            // Mark with a free list node, in case we have a GC before
1161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            // deserializing.
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Address free_space_address = free_space->address();
11633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            CreateFillerObjectAt(free_space_address, size,
11643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 ClearRecordedSlots::kNo);
11653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            DCHECK(space < SerializerDeserializer::kNumberOfPreallocatedSpaces);
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            chunk.start = free_space_address;
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            chunk.end = free_space_address + size;
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          } else {
1169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            perform_gc = true;
1170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            break;
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (perform_gc) {
1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (space == NEW_SPACE) {
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CollectGarbage(NEW_SPACE, "failed to reserve space in the new space");
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (counter > 1) {
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            CollectAllGarbage(
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                kReduceMemoryFootprintMask | kAbortIncrementalMarkingMask,
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                "failed to reserve space in paged or large "
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                "object space, trying to reduce memory footprint");
1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            CollectAllGarbage(
1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                kAbortIncrementalMarkingMask,
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                "failed to reserve space in paged or large object space");
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        gc_performed = true;
1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;  // Abort for-loop over spaces and retry.
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return !gc_performed;
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnsureFromSpaceIsCommitted() {
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (new_space_.CommitFromSpaceIfNeeded()) return;
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Committing memory to from space failed.
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Memory is exhausted and we will die.
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V8::FatalProcessOutOfMemory("Committing semi space failed.");
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ClearNormalizedMapCaches() {
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (isolate_->bootstrapper()->IsActive() &&
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !incremental_marking()->IsMarking()) {
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* context = native_contexts_list();
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!context->IsUndefined()) {
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // GC can happen when the context is not fully initialized,
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // so the cache can be undefined.
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* cache =
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX);
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!cache->IsUndefined()) {
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NormalizedMapCache::cast(cache)->Clear();
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1223bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    context = Context::cast(context)->next_context_link();
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateSurvivalStatistics(int start_new_space_size) {
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (start_new_space_size == 0) return;
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  promotion_ratio_ = (static_cast<double>(promoted_objects_size_) /
1232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                      static_cast<double>(start_new_space_size) * 100);
1233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (previous_semi_space_copied_object_size_ > 0) {
1235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    promotion_rate_ =
1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        (static_cast<double>(promoted_objects_size_) /
1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         static_cast<double>(previous_semi_space_copied_object_size_) * 100);
1238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
1239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    promotion_rate_ = 0;
1240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  semi_space_copied_rate_ =
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (static_cast<double>(semi_space_copied_object_size_) /
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       static_cast<double>(start_new_space_size) * 100);
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  double survival_rate = promotion_ratio_ + semi_space_copied_rate_;
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer()->AddSurvivalRatio(survival_rate);
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (survival_rate > kYoungSurvivalRateHighThreshold) {
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    high_survival_rate_period_length_++;
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    high_survival_rate_period_length_ = 0;
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::PerformGarbageCollection(
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) {
1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int freed_global_handles = 0;
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (collector != SCAVENGER) {
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PROFILE(isolate_, CodeMovingGCEvent());
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VerifyStringTable(this);
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCType gc_type =
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge;
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCCallbacksScope scope(this);
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (scope.CheckReenter()) {
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllowHeapAllocation allow_allocation;
12763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      TRACE_GC(tracer(), collector == MARK_COMPACTOR
12773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             ? GCTracer::Scope::MC_EXTERNAL_PROLOGUE
12783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             : GCTracer::Scope::SCAVENGER_EXTERNAL_PROLOGUE);
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VMState<EXTERNAL> state(isolate_);
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HandleScope handle_scope(isolate_);
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags);
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureFromSpaceIsCommitted();
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int start_new_space_size = Heap::new_space()->SizeAsInt();
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsHighSurvivalRate()) {
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We speed up the incremental marker if it is running so that it
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // does not fall behind the rate of promotion, which would cause a
1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // constantly growing old space.
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    incremental_marking()->NotifyOfHighPromotionRate();
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Heap::PretenuringScope pretenuring_scope(this);
1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (collector == MARK_COMPACTOR) {
1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UpdateOldGenerationAllocationCounter();
1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Perform mark-sweep with optional compaction.
1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MarkCompact();
1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      old_gen_exhausted_ = false;
1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      old_generation_size_configured_ = true;
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This should be updated before PostGarbageCollectionProcessing, which
1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // can cause another GC. Take into account the objects promoted during GC.
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      old_generation_allocation_counter_ +=
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<size_t>(promoted_objects_size_);
1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects();
1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Scavenge();
1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ProcessPretenuringFeedback();
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateSurvivalStatistics(start_new_space_size);
1318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ConfigureInitialOldGenerationSize();
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->objs_since_last_young()->Set(0);
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gc_post_processing_depth_++;
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllowHeapAllocation allow_allocation;
13253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::EXTERNAL_WEAK_GLOBAL_HANDLES);
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    freed_global_handles =
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate_->global_handles()->PostGarbageCollectionProcessing(
1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            collector, gc_callback_flags);
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gc_post_processing_depth_--;
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->eternal_handles()->PostGarbageCollectionProcessing(this);
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update relocatables.
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Relocatable::PostGarbageCollectionProcessing(isolate_);
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double gc_speed = tracer()->CombinedMarkCompactSpeedInBytesPerMillisecond();
13383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  double mutator_speed =
13393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      tracer()->CurrentOldGenerationAllocationThroughputInBytesPerMillisecond();
1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t old_gen_size = PromotedSpaceSizeOfObjects();
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (collector == MARK_COMPACTOR) {
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register the amount of external allocated memory.
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    amount_of_external_allocated_memory_at_last_global_gc_ =
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        amount_of_external_allocated_memory_;
1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed);
1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (HasLowYoungGenerationAllocationRate() &&
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             old_generation_size_configured_) {
1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DampenOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed);
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCCallbacksScope scope(this);
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (scope.CheckReenter()) {
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllowHeapAllocation allow_allocation;
13553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      TRACE_GC(tracer(), collector == MARK_COMPACTOR
13563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             ? GCTracer::Scope::MC_EXTERNAL_EPILOGUE
13573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             : GCTracer::Scope::SCAVENGER_EXTERNAL_EPILOGUE);
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VMState<EXTERNAL> state(isolate_);
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HandleScope handle_scope(isolate_);
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CallGCEpilogueCallbacks(gc_type, gc_callback_flags);
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VerifyStringTable(this);
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return freed_global_handles > 0;
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) {
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (gc_type & gc_prologue_callbacks_[i].gc_type) {
1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!gc_prologue_callbacks_[i].pass_isolate) {
1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        v8::GCCallback callback = reinterpret_cast<v8::GCCallback>(
1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            gc_prologue_callbacks_[i].callback);
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        callback(gc_type, flags);
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        gc_prologue_callbacks_[i].callback(isolate, gc_type, flags);
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
13873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (FLAG_trace_object_groups && (gc_type == kGCTypeIncrementalMarking ||
13883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                   gc_type == kGCTypeMarkSweepCompact)) {
13893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    isolate_->global_handles()->PrintObjectGroups();
13903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CallGCEpilogueCallbacks(GCType gc_type,
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   GCCallbackFlags gc_callback_flags) {
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (gc_type & gc_epilogue_callbacks_[i].gc_type) {
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!gc_epilogue_callbacks_[i].pass_isolate) {
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        v8::GCCallback callback = reinterpret_cast<v8::GCCallback>(
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            gc_epilogue_callbacks_[i].callback);
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        callback(gc_type, gc_callback_flags);
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        gc_epilogue_callbacks_[i].callback(isolate, gc_type, gc_callback_flags);
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MarkCompact() {
1412109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PauseAllocationObserversScope pause_observers(this);
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gc_state_ = MARK_COMPACT;
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, ResourceEvent("markcompact", "begin"));
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t size_of_objects_before_gc = SizeOfObjects();
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mark_compact_collector()->Prepare();
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ms_count_++;
1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MarkCompactPrologue();
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mark_compact_collector()->CollectGarbage();
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, ResourceEvent("markcompact", "end"));
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MarkCompactEpilogue();
1430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_allocation_site_pretenuring) {
1432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    EvaluateOldSpaceLocalPretenuring(size_of_objects_before_gc);
1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Heap::MarkCompactEpilogue() {
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gc_state_ = NOT_IN_GC;
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->counters()->objs_since_last_full()->Set(0);
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  incremental_marking()->Epilogue();
1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PreprocessStackTraces();
14453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(incremental_marking()->IsStopped());
14463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
14473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // We finished a marking cycle. We can uncommit the marking deque until
14483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // we start marking again.
14493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  mark_compact_collector()->marking_deque()->Uninitialize();
14503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  mark_compact_collector()->EnsureMarkingDequeIsCommitted(
14513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      MarkCompactCollector::kMinMarkingDequeSize);
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MarkCompactPrologue() {
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // At any old GC clear the keyed lookup cache to enable collection of unused
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // maps.
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->keyed_lookup_cache()->Clear();
1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->context_slot_cache()->Clear();
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->descriptor_lookup_cache()->Clear();
1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RegExpResultsCache::Clear(string_split_cache());
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RegExpResultsCache::Clear(regexp_multiple_cache());
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->compilation_cache()->MarkCompactPrologue();
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompletelyClearInstanceofCache();
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FlushNumberStringCache();
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ClearNormalizedMapCaches();
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Visitor class to verify pointers in code or data space do not point into
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// new space.
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass VerifyNonPointerSpacePointersVisitor : public ObjectVisitor {
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit VerifyNonPointerSpacePointersVisitor(Heap* heap) : heap_(heap) {}
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Object** current = start; current < end; current++) {
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if ((*current)->IsHeapObject()) {
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!heap_->InNewSpace(HeapObject::cast(*current)));
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap* heap_;
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void VerifyNonPointerSpacePointers(Heap* heap) {
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Verify that there are no pointers to new space in spaces where we
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // do not expect them.
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VerifyNonPointerSpacePointersVisitor v(heap);
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObjectIterator code_it(heap->code_space());
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (HeapObject* object = code_it.Next(); object != NULL;
1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       object = code_it.Next())
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object->Iterate(&v);
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // VERIFY_HEAP
1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CheckNewSpaceExpansionCriteria() {
1506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_experimental_new_space_growth_heuristic) {
1507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
1508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        survived_last_scavenge_ * 100 / new_space_.TotalCapacity() >= 10) {
1509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Grow the size of new space if there is room to grow, and more than 10%
1510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // have survived the last scavenge.
1511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      new_space_.Grow();
1512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      survived_since_last_expansion_ = 0;
1513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
1515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             survived_since_last_expansion_ > new_space_.TotalCapacity()) {
1516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Grow the size of new space if there is room to grow, and enough data
1517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // has survived scavenge since the last expansion.
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    new_space_.Grow();
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    survived_since_last_expansion_ = 0;
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool IsUnscavengedHeapObject(Heap* heap, Object** p) {
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return heap->InNewSpace(*p) &&
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         !HeapObject::cast(*p)->map_word().IsForwardingAddress();
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic bool IsUnmodifiedHeapObject(Object** p) {
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* object = *p;
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (object->IsSmi()) return false;
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* heap_object = HeapObject::cast(object);
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!object->IsJSObject()) return false;
1535bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  JSObject* js_object = JSObject::cast(object);
1536bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (!js_object->WasConstructedFromApiFunction()) return false;
1537bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  JSFunction* constructor =
1538bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      JSFunction::cast(js_object->map()->GetConstructor());
1539bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1540bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return constructor->initial_map() == heap_object->map();
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PromotionQueue::Initialize() {
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The last to-space page may be used for promotion queue. On promotion
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // conflict, we use the emergency stack.
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) ==
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         0);
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  front_ = rear_ =
15503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      reinterpret_cast<struct Entry*>(heap_->new_space()->ToSpaceEnd());
15513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  limit_ = reinterpret_cast<struct Entry*>(
1552bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Page::FromAllocationAreaAddress(reinterpret_cast<Address>(rear_))
1553bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          ->area_start());
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emergency_stack_ = NULL;
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PromotionQueue::RelocateQueueHead() {
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(emergency_stack_ == NULL);
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1561bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Page* p = Page::FromAllocationAreaAddress(reinterpret_cast<Address>(rear_));
15623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  struct Entry* head_start = rear_;
15633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  struct Entry* head_end =
15643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Min(front_, reinterpret_cast<struct Entry*>(p->area_end()));
1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int entries_count =
15673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      static_cast<int>(head_end - head_start) / sizeof(struct Entry);
1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emergency_stack_ = new List<Entry>(2 * entries_count);
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (head_start != head_end) {
15723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    struct Entry* entry = head_start++;
1573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // New space allocation in SemiSpaceCopyObject marked the region
1574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // overlapping with promotion queue as uninitialized.
15753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    MSAN_MEMORY_IS_INITIALIZED(entry, sizeof(struct Entry));
15763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    emergency_stack_->Add(*entry);
1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rear_ = head_end;
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ScavengeWeakObjectRetainer : public WeakObjectRetainer {
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit ScavengeWeakObjectRetainer(Heap* heap) : heap_(heap) {}
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Object* RetainAs(Object* object) {
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!heap_->InFromSpace(object)) {
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return object;
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MapWord map_word = HeapObject::cast(object)->map_word();
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (map_word.IsForwardingAddress()) {
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return map_word.ToForwardingAddress();
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap* heap_;
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::Scavenge() {
16043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_SCAVENGE);
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RelocationLock relocation_lock(this);
1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // There are soft limits in the allocation code, designed to trigger a mark
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // sweep collection by failing allocations. There is no sense in trying to
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // trigger one during scavenge: scavenges allocation should always succeed.
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AlwaysAllocateScope scope(isolate());
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Bump-pointer allocations done during scavenge are not real allocations.
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Pause the inline allocation steps.
1613109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PauseAllocationObserversScope pause_observers(this);
1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) VerifyNonPointerSpacePointers(this);
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gc_state_ = SCAVENGE;
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Implements Cheney's copying algorithm
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, ResourceEvent("scavenge", "begin"));
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Used for updating survived_since_last_expansion_ at function end.
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t survived_watermark = PromotedSpaceSizeOfObjects();
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_collector_->SelectScavengingVisitorsTable();
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array_buffer_tracker()->PrepareDiscoveryInNewSpace();
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Flip the semispaces.  After flipping, to space is empty, from space has
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // live objects.
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_.Flip();
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_.ResetAllocationInfo();
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We need to sweep newly copied objects which can be either in the
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to space or promoted to the old generation.  For to-space
1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects, we treat the bottom of the to space as a queue.  Newly
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // copied and unswept objects lie between a 'front' mark and the
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // allocation pointer.
1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Promoted objects can go into various old-generation spaces, and
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // can be allocated internally in the spaces (from the free list).
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We treat the top of the to space as a queue of addresses of
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // promoted objects.  The addresses of newly promoted and unswept
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects lie between a 'front' mark and a 'rear' mark that is
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // updated as a side effect of promoting an object.
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There is guaranteed to be enough room at the top of the to space
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for the addresses of promoted objects: every object promoted
1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // frees up its size in bytes from the top of the new space, and
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects are at least one pointer in size.
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address new_space_front = new_space_.ToSpaceStart();
1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  promotion_queue_.Initialize();
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ScavengeVisitor scavenge_visitor(this);
1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_scavenge_reclaim_unmodified_objects) {
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->global_handles()->IdentifyWeakUnmodifiedObjects(
1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &IsUnmodifiedHeapObject);
1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Copy roots.
16653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_ROOTS);
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE);
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Copy objects reachable from the old generation.
16713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_OLD_TO_NEW_POINTERS);
1672109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    RememberedSet<OLD_TO_NEW>::IterateWithWrapper(this,
1673109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                                  Scavenger::ScavengeObject);
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
16773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_WEAK);
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Copy objects reachable from the encountered weak collections list.
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    scavenge_visitor.VisitPointer(&encountered_weak_collections_);
1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Copy objects reachable from the encountered weak cells.
1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    scavenge_visitor.VisitPointer(&encountered_weak_cells_);
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Copy objects reachable from the code flushing candidates list.
16863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_CODE_FLUSH_CANDIDATES);
1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MarkCompactCollector* collector = mark_compact_collector();
1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (collector->is_code_flushing_enabled()) {
1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor);
1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
16943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_SEMISPACE);
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_scavenge_reclaim_unmodified_objects) {
1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending(
1700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &IsUnscavengedHeapObject);
1701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->global_handles()->IterateNewSpaceWeakUnmodifiedRoots(
1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &scavenge_visitor);
1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
17063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_OBJECT_GROUPS);
1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (isolate()->global_handles()->IterateObjectGroups(
1708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &scavenge_visitor, &IsUnscavengedHeapObject)) {
1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->global_handles()->RemoveObjectGroups();
1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->global_handles()->RemoveImplicitRefGroups();
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &IsUnscavengedHeapObject);
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->global_handles()->IterateNewSpaceWeakIndependentRoots(
1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        &scavenge_visitor);
1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UpdateNewSpaceReferencesInExternalStringTable(
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      &UpdateNewSpaceReferenceInExternalStringTableEntry);
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  promotion_queue_.Destroy();
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  incremental_marking()->UpdateMarkingDequeAfterScavenge();
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ScavengeWeakObjectRetainer weak_object_retainer(this);
1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ProcessYoungWeakReferences(&weak_object_retainer);
1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(new_space_front == new_space_.top());
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set age mark.
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_.set_age_mark(new_space_.top());
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array_buffer_tracker()->FreeDead(true);
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update how much has survived scavenge.
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IncrementYoungSurvivorsCounter(static_cast<int>(
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size()));
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, ResourceEvent("scavenge", "end"));
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gc_state_ = NOT_IN_GC;
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochString* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                Object** p) {
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapWord first_word = HeapObject::cast(*p)->map_word();
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!first_word.IsForwardingAddress()) {
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Unreachable external string can be finalized.
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap->FinalizeExternalString(String::cast(*p));
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // String is still reachable.
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return String::cast(first_word.ToForwardingAddress());
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateNewSpaceReferencesInExternalStringTable(
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ExternalStringTableUpdaterCallback updater_func) {
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (external_string_table_.new_space_strings_.is_empty()) return;
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** start = &external_string_table_.new_space_strings_[0];
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** end = start + external_string_table_.new_space_strings_.length();
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** last = start;
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (Object** p = start; p < end; ++p) {
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    String* target = updater_func(this, p);
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (target == NULL) continue;
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(target->IsExternalString());
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (InNewSpace(target)) {
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // String is still in new space.  Update the table entry.
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *last = target;
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ++last;
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // String got promoted.  Move it to the old string list.
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      external_string_table_.AddOldString(target);
1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(last <= end);
1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  external_string_table_.ShrinkNewStrings(static_cast<int>(last - start));
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateReferencesInExternalStringTable(
1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ExternalStringTableUpdaterCallback updater_func) {
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update old space string references.
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (external_string_table_.old_space_strings_.length() > 0) {
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** start = &external_string_table_.old_space_strings_[0];
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** end = start + external_string_table_.old_space_strings_.length();
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Object** p = start; p < end; ++p) *p = updater_func(this, p);
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateNewSpaceReferencesInExternalStringTable(updater_func);
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ProcessAllWeakReferences(WeakObjectRetainer* retainer) {
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ProcessNativeContexts(retainer);
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ProcessAllocationSites(retainer);
1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ProcessYoungWeakReferences(WeakObjectRetainer* retainer) {
1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ProcessNativeContexts(retainer);
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) {
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* head = VisitWeakList<Context>(this, native_contexts_list(), retainer);
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update the head of the list of contexts.
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_native_contexts_list(head);
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) {
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* allocation_site_obj =
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitWeakList<AllocationSite>(this, allocation_sites_list(), retainer);
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_allocation_sites_list(allocation_site_obj);
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::ProcessWeakListRoots(WeakObjectRetainer* retainer) {
18323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  set_native_contexts_list(retainer->RetainAs(native_contexts_list()));
18333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  set_allocation_sites_list(retainer->RetainAs(allocation_sites_list()));
18343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) {
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation_scope;
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* cur = allocation_sites_list();
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool marked = false;
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (cur->IsAllocationSite()) {
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationSite* casted = AllocationSite::cast(cur);
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (casted->GetPretenureMode() == flag) {
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      casted->ResetPretenureDecision();
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      casted->set_deopt_dependent_code(true);
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      marked = true;
1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RemoveAllocationSitePretenuringFeedback(casted);
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cur = casted->weak_next();
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (marked) isolate_->stack_guard()->RequestDeoptMarkedAllocationSites();
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EvaluateOldSpaceLocalPretenuring(
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint64_t size_of_objects_before_gc) {
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t size_of_objects_after_gc = SizeOfObjects();
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double old_generation_survival_rate =
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (static_cast<double>(size_of_objects_after_gc) * 100) /
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<double>(size_of_objects_before_gc);
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (old_generation_survival_rate < kOldSurvivalRateLowThreshold) {
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Too many objects died in the old generation, pretenuring of wrong
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // allocation sites may be the cause for that. We have to deopt all
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // dependent code registered in the allocation sites to re-evaluate
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // our pretenuring decisions.
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ResetAllAllocationSitesDependentCode(TENURED);
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_trace_pretenuring) {
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF(
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          "Deopt all allocation sites dependent code due to low survival "
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          "rate in the old generation %f\n",
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          old_generation_survival_rate);
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // All external strings are listed in the external string table.
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class ExternalStringTableVisitorAdapter : public ObjectVisitor {
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit ExternalStringTableVisitorAdapter(
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v8::ExternalResourceVisitor* visitor)
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : visitor_(visitor) {}
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    virtual void VisitPointers(Object** start, Object** end) {
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (Object** p = start; p < end; p++) {
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK((*p)->IsExternalString());
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        visitor_->VisitExternalString(
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Utils::ToLocal(Handle<String>(String::cast(*p))));
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::ExternalResourceVisitor* visitor_;
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } external_string_table_visitor(visitor);
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  external_string_table_.Iterate(&external_string_table_visitor);
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Address new_space_front) {
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SemiSpace::AssertValidRange(new_space_front, new_space_.top());
1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The addresses new_space_front and new_space_.top() define a
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // queue of unprocessed copied objects.  Process them until the
1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // queue is empty.
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (new_space_front != new_space_.top()) {
1910bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!Page::IsAlignedToPageSize(new_space_front)) {
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HeapObject* object = HeapObject::FromAddress(new_space_front);
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        new_space_front +=
1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            StaticScavengeVisitor::IterateBody(object->map(), object);
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1915bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        new_space_front = Page::FromAllocationAreaAddress(new_space_front)
1916bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              ->next_page()
1917bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              ->area_start();
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Promote and process all the to-be-promoted objects.
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      while (!promotion_queue()->is_empty()) {
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HeapObject* target;
19253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        int32_t size;
19263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        bool was_marked_black;
19273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        promotion_queue()->remove(&target, &size, &was_marked_black);
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Promoted object might be already partially visited
1930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // during old space pointer iteration. Thus we search specifically
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // for pointers to from semispace instead of looking for pointers
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // to new space.
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(!target->IsMap());
1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
19353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        IteratePromotedObject(target, static_cast<int>(size), was_marked_black,
19363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                              &Scavenger::ScavengeObject);
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Take another spin if there are now unswept objects in new space
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // (there are currently no more unswept promoted objects).
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (new_space_front != new_space_.top());
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_space_front;
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSTATIC_ASSERT((FixedDoubleArray::kHeaderSize & kDoubleAlignmentMask) ==
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              0);  // NOLINT
1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSTATIC_ASSERT((FixedTypedArrayBase::kDataOffset & kDoubleAlignmentMask) ==
1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              0);  // NOLINT
1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef V8_HOST_ARCH_32_BIT
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSTATIC_ASSERT((HeapNumber::kValueOffset & kDoubleAlignmentMask) !=
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              0);  // NOLINT
1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Heap::GetMaximumFillToAlign(AllocationAlignment alignment) {
1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (alignment) {
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kWordAligned:
1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 0;
1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDoubleAligned:
1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDoubleUnaligned:
1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kDoubleSize - kPointerSize;
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSimd128Unaligned:
1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kSimd128Size - kPointerSize;
1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return 0;
1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Heap::GetFillToAlign(Address address, AllocationAlignment alignment) {
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t offset = OffsetFrom(address);
1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (alignment == kDoubleAligned && (offset & kDoubleAlignmentMask) != 0)
1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return kPointerSize;
1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (alignment == kDoubleUnaligned && (offset & kDoubleAlignmentMask) == 0)
1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return kDoubleSize - kPointerSize;  // No fill if double is always aligned.
1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (alignment == kSimd128Unaligned) {
1981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return (kSimd128Size - (static_cast<int>(offset) + kPointerSize)) &
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           kSimd128AlignmentMask;
1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return 0;
1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHeapObject* Heap::PrecedeWithFiller(HeapObject* object, int filler_size) {
19893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CreateFillerObjectAt(object->address(), filler_size, ClearRecordedSlots::kNo);
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HeapObject::FromAddress(object->address() + filler_size);
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHeapObject* Heap::AlignWithFiller(HeapObject* object, int object_size,
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  int allocation_size,
1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  AllocationAlignment alignment) {
1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int filler_size = allocation_size - object_size;
1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(filler_size > 0);
1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pre_filler = GetFillToAlign(object->address(), alignment);
2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pre_filler) {
2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    object = PrecedeWithFiller(object, pre_filler);
2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    filler_size -= pre_filler;
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (filler_size)
20053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CreateFillerObjectAt(object->address() + object_size, filler_size,
20063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                         ClearRecordedSlots::kNo);
2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return object;
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHeapObject* Heap::DoubleAlignForDeserialization(HeapObject* object, int size) {
2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AlignWithFiller(object, size - kPointerSize, size, kDoubleAligned);
2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RegisterNewArrayBuffer(JSArrayBuffer* buffer) {
2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return array_buffer_tracker()->RegisterNew(buffer);
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::UnregisterArrayBuffer(JSArrayBuffer* buffer) {
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return array_buffer_tracker()->Unregister(buffer);
2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Heap::ConfigureInitialOldGenerationSize() {
2027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!old_generation_size_configured_ && tracer()->SurvivalEventsRecorded()) {
2028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    old_generation_allocation_limit_ =
2029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Max(kMinimumOldGenerationAllocationLimit,
2030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            static_cast<intptr_t>(
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                static_cast<double>(old_generation_allocation_limit_) *
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                (tracer()->AverageSurvivalRatio() / 100)));
2033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          int instance_size) {
2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* result = nullptr;
2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE);
2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Map::cast cannot be used due to uninitialized map field.
2044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  reinterpret_cast<Map*>(result)->set_map(
2045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      reinterpret_cast<Map*>(root(kMetaMapRootIndex)));
2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_instance_type(instance_type);
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_instance_size(instance_size);
2048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Initialize to only containing tagged fields.
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_visitor_id(
2050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      StaticVisitorBase::GetVisitorId(instance_type, instance_size, false));
2051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_unbox_double_fields) {
2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    reinterpret_cast<Map*>(result)
2053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        ->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  reinterpret_cast<Map*>(result)->clear_unused();
2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  reinterpret_cast<Map*>(result)
2057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ->set_inobject_properties_or_constructor_function_index(0);
2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_bit_field(0);
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_bit_field2(0);
2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
2062958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   Map::OwnsDescriptors::encode(true) |
2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   Map::ConstructionCounter::encode(Map::kNoSlackTracking);
2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3);
2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  reinterpret_cast<Map*>(result)->set_weak_cell_cache(Smi::FromInt(0));
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateMap(InstanceType instance_type,
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   int instance_size,
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   ElementsKind elements_kind) {
2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE);
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2077109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  isolate()->counters()->maps_created()->Increment();
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(meta_map());
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = Map::cast(result);
2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_instance_type(instance_type);
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_prototype(null_value(), SKIP_WRITE_BARRIER);
2082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_constructor_or_backpointer(null_value(), SKIP_WRITE_BARRIER);
2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_instance_size(instance_size);
2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->clear_unused();
2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_inobject_properties_or_constructor_function_index(0);
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_dependent_code(DependentCode::cast(empty_fixed_array()),
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          SKIP_WRITE_BARRIER);
2089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_weak_cell_cache(Smi::FromInt(0));
2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_raw_transitions(Smi::FromInt(0));
2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_unused_property_fields(0);
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_instance_descriptors(empty_descriptor_array());
2093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_unbox_double_fields) {
2094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
2095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Must be called only after |instance_type|, |instance_size| and
2097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // |layout_descriptor| are set.
2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_visitor_id(Heap::GetStaticVisitorIdForMap(map));
2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_bit_field(0);
2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_bit_field2(1 << Map::kIsExtensible);
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
2102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   Map::OwnsDescriptors::encode(true) |
2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   Map::ConstructionCounter::encode(Map::kNoSlackTracking);
2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_bit_field3(bit_field3);
2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map->set_elements_kind(elements_kind);
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map->set_new_target_is_base(true);
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return map;
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFillerObject(int size, bool double_align,
2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            AllocationSpace space) {
2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationAlignment align = double_align ? kDoubleAligned : kWordAligned;
2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space, align);
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(chunk->owner()->identity() == space);
2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
21243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CreateFillerObjectAt(obj->address(), size, ClearRecordedSlots::kNo);
2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj;
2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Heap::StringTypeTable Heap::string_type_table[] = {
2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define STRING_TYPE_ELEMENT(type, size, name, camel_name) \
2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  { type, size, k##camel_name##MapRootIndex }             \
2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ,
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STRING_TYPE_LIST(STRING_TYPE_ELEMENT)
2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef STRING_TYPE_ELEMENT
2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Heap::ConstantStringTable Heap::constant_string_table[] = {
2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    {"", kempty_stringRootIndex},
2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CONSTANT_STRING_ELEMENT(name, contents) \
2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  { contents, k##name##RootIndex }              \
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ,
2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT)
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef CONSTANT_STRING_ELEMENT
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Heap::StructTable Heap::struct_table[] = {
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define STRUCT_TABLE_ELEMENT(NAME, Name, name)        \
2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  { NAME##_TYPE, Name::kSize, k##Name##MapRootIndex } \
2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ,
2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STRUCT_LIST(STRUCT_TABLE_ELEMENT)
2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef STRUCT_TABLE_ELEMENT
2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2156bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochnamespace {
2157bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2158bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid FinalizePartialMap(Heap* heap, Map* map) {
2159bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_code_cache(heap->empty_fixed_array());
2160bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_dependent_code(DependentCode::cast(heap->empty_fixed_array()));
2161bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_raw_transitions(Smi::FromInt(0));
2162bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_instance_descriptors(heap->empty_descriptor_array());
2163bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (FLAG_unbox_double_fields) {
2164bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
2165bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2166bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_prototype(heap->null_value());
2167bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  map->set_constructor_or_backpointer(heap->null_value());
2168bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
2169bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2170bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}  // namespace
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CreateInitialMaps() {
2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize);
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Map::cast cannot be used due to uninitialized map field.
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* new_meta_map = reinterpret_cast<Map*>(obj);
2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_meta_map(new_meta_map);
2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_meta_map->set_map(new_meta_map);
2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {  // Partial map allocation
2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name)                \
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {                                                                          \
2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Map* map;                                                                \
2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocatePartialMap((instance_type), (size)).To(&map)) return false; \
2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_##field_name##_map(map);                                             \
2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array);
2192bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    fixed_array_map()->set_elements_kind(FAST_HOLEY_ELEMENTS);
2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined);
2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null);
2195bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole);
2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_PARTIAL_MAP
2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the empty array.
2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateEmptyFixedArray();
2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_empty_fixed_array(FixedArray::cast(obj));
2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = Allocate(null_map(), OLD_SPACE);
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_null_value(Oddball::cast(obj));
2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Oddball::cast(obj)->set_kind(Oddball::kNull);
2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = Allocate(undefined_map(), OLD_SPACE);
2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_undefined_value(Oddball::cast(obj));
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Oddball::cast(obj)->set_kind(Oddball::kUndefined);
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(undefined_value()));
2221bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  {
2222bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    AllocationResult allocation = Allocate(the_hole_map(), OLD_SPACE);
2223bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!allocation.To(&obj)) return false;
2224bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2225bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  set_the_hole_value(Oddball::cast(obj));
2226bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Oddball::cast(obj)->set_kind(Oddball::kTheHole);
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set preliminary exception sentinel value before actually initializing it.
2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_exception(null_value());
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the empty descriptor array.
2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateEmptyFixedArray();
2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return false;
2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_empty_descriptor_array(DescriptorArray::cast(obj));
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fix the instance_descriptors for the existing maps.
2239bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, meta_map());
2240bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, fixed_array_map());
2241bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, undefined_map());
2242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  undefined_map()->set_is_undetectable();
2243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, null_map());
2244bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  null_map()->set_is_undetectable();
2245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FinalizePartialMap(this, the_hole_map());
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {  // Map allocation
2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_MAP(instance_type, size, field_name)               \
2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {                                                                 \
2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Map* map;                                                       \
2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocateMap((instance_type), size).To(&map)) return false; \
2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_##field_name##_map(map);                                    \
2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \
2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name)
2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATE_PRIMITIVE_MAP(instance_type, size, field_name, \
2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               constructor_function_index)      \
2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {                                                             \
2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_MAP((instance_type), (size), field_name);          \
2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    field_name##_map()->SetConstructorFunctionIndex(            \
2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (constructor_function_index));                          \
2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, fixed_cow_array)
2267bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    fixed_cow_array_map()->set_elements_kind(FAST_HOLEY_ELEMENTS);
2268bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK_NE(fixed_array_map(), fixed_cow_array_map());
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info)
2271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
2272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           Context::NUMBER_FUNCTION_INDEX)
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 mutable_heap_number)
2275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol,
2276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           Context::SYMBOL_FUNCTION_INDEX)
2277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ALLOCATE_SIMD128_MAP(TYPE, Type, type, lane_count, lane_type) \
2278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ALLOCATE_PRIMITIVE_MAP(SIMD128_VALUE_TYPE, Type::kSize, type,       \
2279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         Context::TYPE##_FUNCTION_INDEX)
2280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SIMD128_TYPES(ALLOCATE_SIMD128_MAP)
2281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef ALLOCATE_SIMD128_MAP
2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign)
2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_PRIMITIVE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean,
2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           Context::BOOLEAN_FUNCTION_INDEX);
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized);
2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker);
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, no_interceptor_result_sentinel);
2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception);
2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception);
22913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, optimized_out);
2292bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, stale_register);
2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (unsigned i = 0; i < arraysize(string_type_table); i++) {
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const StringTypeTable& entry = string_type_table[i];
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      {
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        AllocationResult allocation = AllocateMap(entry.type, entry.size);
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!allocation.To(&obj)) return false;
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Map* map = Map::cast(obj);
2301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Mark cons string maps as unstable, because their objects can change
2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // maps during GC.
2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (StringShape(entry.type).IsCons()) map->mark_unstable();
2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      roots_[entry.index] = map;
2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    {  // Create a separate external one byte string map for native sources.
2309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      AllocationResult allocation = AllocateMap(EXTERNAL_ONE_BYTE_STRING_TYPE,
2310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                ExternalOneByteString::kSize);
2311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (!allocation.To(&obj)) return false;
2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Map* map = Map::cast(obj);
2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
2314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      set_native_source_string_map(map);
2315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_DOUBLE_ARRAY_TYPE, fixed_double_array)
2318bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    fixed_double_array_map()->set_elements_kind(FAST_HOLEY_DOUBLE_ELEMENTS);
2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(BYTE_ARRAY_TYPE, byte_array)
2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_VARSIZE_MAP(BYTECODE_ARRAY_TYPE, bytecode_array)
2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FREE_SPACE_TYPE, free_space)
2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_FIXED_TYPED_ARRAY_MAP(Type, type, TYPE, ctype, size) \
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ALLOCATE_VARSIZE_MAP(FIXED_##TYPE##_ARRAY_TYPE, fixed_##type##_array)
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(ALLOCATE_FIXED_TYPED_ARRAY_MAP)
2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_FIXED_TYPED_ARRAY_MAP
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements)
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell)
2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell)
2335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ALLOCATE_MAP(WEAK_CELL_TYPE, WeakCell::kSize, weak_cell)
2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler)
2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler)
2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ALLOCATE_VARSIZE_MAP(TRANSITION_ARRAY_TYPE, transition_array)
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (unsigned i = 0; i < arraysize(struct_table); i++) {
2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const StructTable& entry = struct_table[i];
2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Map* map;
2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!AllocateMap(entry.type, entry.size).To(&map)) return false;
2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      roots_[entry.index] = map;
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, hash_table)
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, ordered_hash_table)
2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context)
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context)
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, with_context)
23543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, debug_evaluate_context)
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, block_context)
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_context)
2357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context)
2358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context_table)
2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, native_context)
2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    native_context_map()->set_dictionary_map(true);
2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    native_context_map()->set_visitor_id(
2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        StaticVisitorBase::kVisitNativeContext);
2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kAlignedSize,
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 shared_function_info)
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kSize, message_object)
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, external)
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    external_map()->set_is_extensible(false);
2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef ALLOCATE_PRIMITIVE_MAP
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_VARSIZE_MAP
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_MAP
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  {
23773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE);
23783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (!allocation.To(&obj)) return false;
23793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
23803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  set_true_value(Oddball::cast(obj));
23813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Oddball::cast(obj)->set_kind(Oddball::kTrue);
23823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
23833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  {
23843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE);
23853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (!allocation.To(&obj)) return false;
23863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
23873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  set_false_value(Oddball::cast(obj));
23883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Oddball::cast(obj)->set_kind(Oddball::kFalse);
23893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {  // Empty arrays
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ByteArray* byte_array;
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false;
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_empty_byte_array(byte_array);
2395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {                                                                     \
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FixedTypedArrayBase* obj;                                           \
2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array).To(&obj)) \
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;                                                     \
2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_empty_fixed_##type##_array(obj);                                \
2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(ALLOCATE_EMPTY_FIXED_TYPED_ARRAY)
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ALLOCATE_EMPTY_FIXED_TYPED_ARRAY
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(empty_fixed_array()));
2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateHeapNumber(double value, MutableMode mode,
2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          PretenureFlag pretenure) {
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Statically ensure that it is safe to allocate heap numbers in paged
2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // spaces.
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = HeapNumber::kSize;
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxRegularHeapObjectSize);
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space, kDoubleUnaligned);
2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = mode == MUTABLE ? mutable_heap_number_map() : heap_number_map();
2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject::cast(result)->set_map_no_write_barrier(map);
2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapNumber::cast(result)->set_value(value);
2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SIMD_ALLOCATE_DEFINITION(TYPE, Type, type, lane_count, lane_type) \
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult Heap::Allocate##Type(lane_type lanes[lane_count],      \
2436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        PretenureFlag pretenure) {        \
2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int size = Type::kSize;                                               \
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    STATIC_ASSERT(Type::kSize <= Page::kMaxRegularHeapObjectSize);        \
2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                                          \
2440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationSpace space = SelectSpace(pretenure);                       \
2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                                          \
2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    HeapObject* result = nullptr;                                         \
2443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    {                                                                     \
2444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocationResult allocation =                                       \
2445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          AllocateRaw(size, space, kSimd128Unaligned);                    \
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!allocation.To(&result)) return allocation;                     \
2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                                     \
2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                                          \
2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->set_map_no_write_barrier(type##_map());                       \
2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Type* instance = Type::cast(result);                                  \
2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < lane_count; i++) {                                \
2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      instance->set_lane(i, lanes[i]);                                    \
2453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                                     \
2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return result;                                                        \
2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSIMD128_TYPES(SIMD_ALLOCATE_DEFINITION)
2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef SIMD_ALLOCATE_DEFINITION
2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateCell(Object* value) {
2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = Cell::kSize;
2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(Cell::kSize <= Page::kMaxRegularHeapObjectSize);
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(cell_map());
2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Cell::cast(result)->set_value(value);
2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocatePropertyCell() {
2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = PropertyCell::kSize;
2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(PropertyCell::kSize <= Page::kMaxRegularHeapObjectSize);
2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(global_property_cell_map());
2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PropertyCell* cell = PropertyCell::cast(result);
2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cell->set_dependent_code(DependentCode::cast(empty_fixed_array()),
2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           SKIP_WRITE_BARRIER);
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cell->set_property_details(PropertyDetails(Smi::FromInt(0)));
2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cell->set_value(the_hole_value());
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAllocationResult Heap::AllocateWeakCell(HeapObject* value) {
2494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int size = WeakCell::kSize;
2495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  STATIC_ASSERT(WeakCell::kSize <= Page::kMaxRegularHeapObjectSize);
2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  {
2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
2499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!allocation.To(&result)) return allocation;
2500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  result->set_map_no_write_barrier(weak_cell_map());
2502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  WeakCell::cast(result)->initialize(value);
2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WeakCell::cast(result)->clear_next(the_hole_value());
2504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return result;
2505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocationResult Heap::AllocateTransitionArray(int capacity) {
2509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(capacity > 0);
2510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* raw_array = nullptr;
2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRawFixedArray(capacity, TENURED);
2513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!allocation.To(&raw_array)) return allocation;
2514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  raw_array->set_map_no_write_barrier(transition_array_map());
2516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TransitionArray* array = TransitionArray::cast(raw_array);
2517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array->set_length(capacity);
2518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MemsetPointer(array->data_start(), undefined_value(), capacity);
25193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Transition arrays are tenured. When black allocation is on we have to
25203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // add the transition array to the list of encountered_transition_arrays.
25213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (incremental_marking()->black_allocation()) {
25223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    array->set_next_link(encountered_transition_arrays(),
25233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                         UPDATE_WEAK_WRITE_BARRIER);
25243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    set_encountered_transition_arrays(array);
25253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
25263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    array->set_next_link(undefined_value(), SKIP_WRITE_BARRIER);
25273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return array;
2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateApiObjects() {
2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate());
2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Factory* factory = isolate()->factory();
2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Map> new_neander_map =
2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Don't use Smi-only elements optimizations for objects with the neander
2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // map. There are too many cases where element values are set directly with a
2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // bottleneck to trap the Smi-only -> fast elements transition, and there
2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // appears to be no benefit for optimize this case.
2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_neander_map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND);
2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_neander_map(*new_neander_map);
2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSObject> listeners = factory->NewNeanderObject();
2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArray> elements = factory->NewFixedArray(2);
2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  elements->set(0, Smi::FromInt(0));
2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  listeners->set_elements(*elements);
2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_message_listeners(*listeners);
2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateJSEntryStub() {
2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSEntryStub stub(isolate(), StackFrame::ENTRY);
2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_js_entry_code(*stub.GetCode());
2556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateJSConstructEntryStub() {
2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSEntryStub stub(isolate(), StackFrame::ENTRY_CONSTRUCT);
2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_js_construct_entry_code(*stub.GetCode());
2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateFixedStubs() {
2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Here we create roots for fixed stubs. They are needed at GC
2567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for cooking and uncooking (check out frames.cc).
2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The eliminates the need for doing dictionary lookup in the
2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // stub cache for these stubs.
2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate());
2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create stubs that should be there, so we don't unexpectedly have to
2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // create them if we need them during the creation of another stub.
2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Stub creation mixes raw pointers and handles in an unsafe manner so
2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we cannot create stubs while we are creating stubs.
2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeStub::GenerateStubsAheadOfTime(isolate());
2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // MacroAssembler::Abort calls (usually enabled with --debug-code) depend on
2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // CEntryStub, so we need to call GenerateStubsAheadOfTime before JSEntryStub
2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // is created.
2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // gcc-4.4 has problem generating correct code of following snippet:
2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // {  JSEntryStub stub;
2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    js_entry_code_ = *stub.GetCode();
2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // }
2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // {  JSConstructEntryStub stub;
2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //    js_construct_entry_code_ = *stub.GetCode();
2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // }
2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // To workaround the problem, make separate functions without inlining.
2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap::CreateJSEntryStub();
2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap::CreateJSConstructEntryStub();
2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::CreateInitialObjects() {
2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate());
2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Factory* factory = isolate()->factory();
2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The -0 value must be set before NewNumber works.
2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_minus_zero_value(*factory->NewHeapNumber(-0.0, IMMUTABLE, TENURED));
2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(std::signbit(minus_zero_value()->Number()) != 0);
2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_nan_value(*factory->NewHeapNumber(
2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      std::numeric_limits<double>::quiet_NaN(), IMMUTABLE, TENURED));
2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, IMMUTABLE, TENURED));
2606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_minus_infinity_value(
2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewHeapNumber(-V8_INFINITY, IMMUTABLE, TENURED));
2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate initial string table.
2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_string_table(*StringTable::New(isolate(), kInitialStringTableSize));
2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
26123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Allocate
26133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Finish initializing oddballs after creating the string table.
2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Oddball::Initialize(isolate(), factory->undefined_value(), "undefined",
26163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      factory->nan_value(), false, "undefined",
26173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      Oddball::kUndefined);
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize the null_value.
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Oddball::Initialize(isolate(), factory->null_value(), "null",
26213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      handle(Smi::FromInt(0), isolate()), false, "object",
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      Oddball::kNull);
2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2624bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Initialize the_hole_value.
2625bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Oddball::Initialize(isolate(), factory->the_hole_value(), "hole",
2626bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                      handle(Smi::FromInt(-1), isolate()), false, "undefined",
2627bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                      Oddball::kTheHole);
2628bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
26293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Initialize the true_value.
26303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Oddball::Initialize(isolate(), factory->true_value(), "true",
26313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      handle(Smi::FromInt(1), isolate()), true, "boolean",
26323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      Oddball::kTrue);
2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
26343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Initialize the false_value.
26353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Oddball::Initialize(isolate(), factory->false_value(), "false",
26363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      handle(Smi::FromInt(0), isolate()), false, "boolean",
26373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      Oddball::kFalse);
2638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_uninitialized_value(
2640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewOddball(factory->uninitialized_map(), "uninitialized",
26413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           handle(Smi::FromInt(-1), isolate()), false,
26423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           "undefined", Oddball::kUninitialized));
2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_arguments_marker(
2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewOddball(factory->arguments_marker_map(), "arguments_marker",
26463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           handle(Smi::FromInt(-4), isolate()), false,
26473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           "undefined", Oddball::kArgumentsMarker));
2648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_no_interceptor_result_sentinel(*factory->NewOddball(
2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      factory->no_interceptor_result_sentinel_map(),
2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "no_interceptor_result_sentinel", handle(Smi::FromInt(-2), isolate()),
26523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      false, "undefined", Oddball::kOther));
2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_termination_exception(*factory->NewOddball(
2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      factory->termination_exception_map(), "termination_exception",
26563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      handle(Smi::FromInt(-3), isolate()), false, "undefined",
26573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Oddball::kOther));
2658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_exception(*factory->NewOddball(factory->exception_map(), "exception",
26603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                     handle(Smi::FromInt(-5), isolate()), false,
2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     "undefined", Oddball::kException));
2662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
26633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  set_optimized_out(
26643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      *factory->NewOddball(factory->optimized_out_map(), "optimized_out",
26653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           handle(Smi::FromInt(-6), isolate()), false,
26663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           "undefined", Oddball::kOptimizedOut));
26673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2668bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  set_stale_register(
2669bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      *factory->NewOddball(factory->stale_register_map(), "stale_register",
2670bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           handle(Smi::FromInt(-7), isolate()), false,
2671bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           "undefined", Oddball::kStaleRegister));
2672bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (unsigned i = 0; i < arraysize(constant_string_table); i++) {
2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<String> str =
2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        factory->InternalizeUtf8String(constant_string_table[i].contents);
2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    roots_[constant_string_table[i].index] = *str;
2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create the code_stubs dictionary. The initial size is set to avoid
2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // expanding the dictionary during bootstrapping.
2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_code_stubs(*UnseededNumberDictionary::New(isolate(), 128));
2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_instanceof_cache_function(Smi::FromInt(0));
2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_instanceof_cache_map(Smi::FromInt(0));
2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_instanceof_cache_answer(Smi::FromInt(0));
2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  {
2688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    HandleScope scope(isolate());
2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SYMBOL_INIT(name)                                              \
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {                                                                    \
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<String> name##d = factory->NewStringFromStaticChars(#name); \
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Symbol> symbol(isolate()->factory()->NewPrivateSymbol());   \
2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    symbol->set_name(*name##d);                                        \
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    roots_[k##name##RootIndex] = *symbol;                              \
2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PRIVATE_SYMBOL_LIST(SYMBOL_INIT)
2697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef SYMBOL_INIT
2698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  {
2701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    HandleScope scope(isolate());
2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SYMBOL_INIT(name, description)                                      \
2703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<Symbol> name = factory->NewSymbol();                               \
2704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<String> name##d = factory->NewStringFromStaticChars(#description); \
2705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  name->set_name(*name##d);                                                 \
2706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  roots_[k##name##RootIndex] = *name;
2707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PUBLIC_SYMBOL_LIST(SYMBOL_INIT)
2708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef SYMBOL_INIT
2709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SYMBOL_INIT(name, description)                                      \
2711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Symbol> name = factory->NewSymbol();                               \
2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<String> name##d = factory->NewStringFromStaticChars(#description); \
2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  name->set_is_well_known_symbol(true);                                     \
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  name->set_name(*name##d);                                                 \
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  roots_[k##name##RootIndex] = *name;
2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WELL_KNOWN_SYMBOL_LIST(SYMBOL_INIT)
2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef SYMBOL_INIT
2718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the dictionary of intrinsic function names.
2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<NameDictionary> intrinsic_names =
2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NameDictionary::New(isolate(), Runtime::kNumFunctions, TENURED);
2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Runtime::InitializeIntrinsicFunctionNames(isolate(), intrinsic_names);
2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_intrinsic_function_names(*intrinsic_names);
2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<NameDictionary> empty_properties_dictionary =
2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      NameDictionary::New(isolate(), 0, TENURED);
2728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  empty_properties_dictionary->SetRequiresCopyOnCapacityChange();
2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_empty_properties_dictionary(*empty_properties_dictionary);
2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_number_string_cache(
2732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *factory->NewFixedArray(kInitialNumberStringCacheSize * 2, TENURED));
2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate cache for single character one byte strings.
2735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_single_character_string_cache(
2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *factory->NewFixedArray(String::kMaxOneByteCharCode + 1, TENURED));
2737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate cache for string split and regexp-multiple.
2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_string_split_cache(*factory->NewFixedArray(
2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
2741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_regexp_multiple_cache(*factory->NewFixedArray(
2742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
2743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate cache for external strings pointing to native source code.
2745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_natives_source_cache(
2746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *factory->NewFixedArray(Natives::GetBuiltinsCount()));
2747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_experimental_natives_source_cache(
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewFixedArray(ExperimentalNatives::GetBuiltinsCount()));
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_extra_natives_source_cache(
2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewFixedArray(ExtraNatives::GetBuiltinsCount()));
2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_experimental_extra_natives_source_cache(
2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *factory->NewFixedArray(ExperimentalExtraNatives::GetBuiltinsCount()));
2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_undefined_cell(*factory->NewCell(factory->undefined_value()));
2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The symbol registry is initialized lazily.
2760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  set_symbol_registry(Smi::FromInt(0));
2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Microtask queue uses the empty fixed array as a sentinel for "empty".
2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of queued microtasks stored in Isolate::pending_microtask_count().
2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_microtask_queue(empty_fixed_array());
2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StaticFeedbackVectorSpec spec;
2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FeedbackVectorSlot load_ic_slot = spec.AddLoadICSlot();
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FeedbackVectorSlot keyed_load_ic_slot = spec.AddKeyedLoadICSlot();
2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FeedbackVectorSlot store_ic_slot = spec.AddStoreICSlot();
2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FeedbackVectorSlot keyed_store_ic_slot = spec.AddKeyedStoreICSlot();
2772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(load_ic_slot,
2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              FeedbackVectorSlot(TypeFeedbackVector::kDummyLoadICSlot));
2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(keyed_load_ic_slot,
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedLoadICSlot));
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(store_ic_slot,
2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              FeedbackVectorSlot(TypeFeedbackVector::kDummyStoreICSlot));
2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(keyed_store_ic_slot,
2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<TypeFeedbackMetadata> dummy_metadata =
2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        TypeFeedbackMetadata::New(isolate(), &spec);
2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<TypeFeedbackVector> dummy_vector =
2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        TypeFeedbackVector::New(isolate(), dummy_metadata);
2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object* megamorphic = *TypeFeedbackVector::MegamorphicSentinel(isolate());
2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    dummy_vector->Set(load_ic_slot, megamorphic, SKIP_WRITE_BARRIER);
2789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    dummy_vector->Set(keyed_load_ic_slot, megamorphic, SKIP_WRITE_BARRIER);
2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    dummy_vector->Set(store_ic_slot, megamorphic, SKIP_WRITE_BARRIER);
2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    dummy_vector->Set(keyed_store_ic_slot, megamorphic, SKIP_WRITE_BARRIER);
2792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_dummy_vector(*dummy_vector);
2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<WeakCell> cell = factory->NewWeakCell(factory->undefined_value());
2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_empty_weak_cell(*cell);
2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cell->clear();
2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<FixedArray> cleared_optimized_code_map =
2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory->NewFixedArray(SharedFunctionInfo::kEntriesStart, TENURED);
2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cleared_optimized_code_map->set(SharedFunctionInfo::kSharedCodeIndex,
2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    *cell);
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    STATIC_ASSERT(SharedFunctionInfo::kEntriesStart == 1 &&
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  SharedFunctionInfo::kSharedCodeIndex == 0);
2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_cleared_optimized_code_map(*cleared_optimized_code_map);
2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_detached_contexts(empty_fixed_array());
2811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_retained_maps(ArrayList::cast(empty_fixed_array()));
2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_weak_object_to_code_table(
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *WeakHashTable::New(isolate(), 16, USE_DEFAULT_MINIMUM_CAPACITY,
2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          TENURED));
2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_script_list(Smi::FromInt(0));
2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<SeededNumberDictionary> slow_element_dictionary =
2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SeededNumberDictionary::New(isolate(), 0, TENURED);
2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  slow_element_dictionary->set_requires_slow_elements();
2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_empty_slow_element_dictionary(*slow_element_dictionary);
2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_materialized_objects(*factory->NewFixedArray(0, TENURED));
2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handling of script id generation is in Heap::NextScriptId().
2827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId));
2828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate the empty script.
2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Script> script = factory->NewScript(factory->empty_string());
2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  script->set_type(Script::TYPE_NATIVE);
2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_empty_script(*script);
2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<PropertyCell> cell = factory->NewPropertyCell();
2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cell->set_value(Smi::FromInt(Isolate::kArrayProtectorValid));
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_array_protector(*cell);
2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cell = factory->NewPropertyCell();
2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cell->set_value(the_hole_value());
2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_empty_property_cell(*cell);
2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2842bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  cell = factory->NewPropertyCell();
2843bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  cell->set_value(Smi::FromInt(Isolate::kArrayProtectorValid));
2844bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  set_has_instance_protector(*cell);
2845bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2846bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Handle<Cell> is_concat_spreadable_cell = factory->NewCell(
2847bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      handle(Smi::FromInt(Isolate::kArrayProtectorValid), isolate()));
2848bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  set_is_concat_spreadable_protector(*is_concat_spreadable_cell);
2849bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2850bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Handle<Cell> species_cell = factory->NewCell(
2851bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      handle(Smi::FromInt(Isolate::kArrayProtectorValid), isolate()));
2852109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  set_species_protector(*species_cell);
2853109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_weak_stack_trace_list(Smi::FromInt(0));
2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_noscript_shared_function_infos(Smi::FromInt(0));
2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize keyed lookup cache.
2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->keyed_lookup_cache()->Clear();
2860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize context slot cache.
2862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->context_slot_cache()->Clear();
2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize descriptor cache.
2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->descriptor_lookup_cache()->Clear();
2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize compilation cache.
2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->compilation_cache()->Clear();
2869bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2870bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CreateFixedStubs();
2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (root_index) {
2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNumberStringCacheRootIndex:
2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInstanceofCacheFunctionRootIndex:
2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInstanceofCacheMapRootIndex:
2879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kInstanceofCacheAnswerRootIndex:
2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCodeStubsRootIndex:
2881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kEmptyScriptRootIndex:
2882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSymbolRegistryRootIndex:
2883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kScriptListRootIndex:
2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMaterializedObjectsRootIndex:
2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMicrotaskQueueRootIndex:
2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kDetachedContextsRootIndex:
2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kWeakObjectToCodeTableRootIndex:
2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kRetainedMapsRootIndex:
2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNoScriptSharedFunctionInfosRootIndex:
2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kWeakStackTraceListRootIndex:
2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Smi values
2892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SMI_ENTRY(type, name, Name) case k##Name##RootIndex:
2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SMI_ROOT_LIST(SMI_ENTRY)
2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef SMI_ENTRY
2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // String table
2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kStringTableRootIndex:
2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::RootCanBeTreatedAsConstant(RootListIndex root_index) {
2906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return !RootCanBeWrittenAfterInitialization(root_index) &&
2907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         !InNewSpace(root(root_index));
2908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Heap::FullSizeNumberStringCacheLength() {
2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the size of the number string cache based on the max newspace size.
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The number string cache has a minimum size based on twice the initial cache
2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // size to ensure that it is bigger after being made 'full size'.
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int number_string_cache_size = max_semi_space_size_ / 512;
2916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  number_string_cache_size = Max(kInitialNumberStringCacheSize * 2,
2917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Min(0x4000, number_string_cache_size));
2918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // There is a string and a number per entry so the length is twice the number
2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of entries.
2920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return number_string_cache_size * 2;
2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::FlushNumberStringCache() {
2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Flush the number to string cache.
2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int len = number_string_cache()->length();
2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < len; i++) {
2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    number_string_cache()->set_undefined(i);
2929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMap* Heap::MapForFixedTypedArray(ExternalArrayType array_type) {
2934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Map::cast(roots_[RootIndexForFixedTypedArray(array_type)]);
2935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::RootListIndex Heap::RootIndexForFixedTypedArray(
2939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ExternalArrayType array_type) {
2940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (array_type) {
2941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ARRAY_TYPE_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \
2942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case kExternal##Type##Array:                                  \
2943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return kFixed##Type##ArrayMapRootIndex;
2944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(ARRAY_TYPE_TO_ROOT_INDEX)
2946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ARRAY_TYPE_TO_ROOT_INDEX
2947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
2949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
2950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kUndefinedValueRootIndex;
2951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeap::RootListIndex Heap::RootIndexForEmptyFixedTypedArray(
2956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ElementsKind elementsKind) {
2957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (elementsKind) {
2958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ELEMENT_KIND_TO_ROOT_INDEX(Type, type, TYPE, ctype, size) \
2959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case TYPE##_ELEMENTS:                                           \
2960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return kEmptyFixed##Type##ArrayRootIndex;
2961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(ELEMENT_KIND_TO_ROOT_INDEX)
2963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ELEMENT_KIND_TO_ROOT_INDEX
2964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
2965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
2966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kUndefinedValueRootIndex;
2967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFixedTypedArrayBase* Heap::EmptyFixedTypedArrayForMap(Map* map) {
2972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return FixedTypedArrayBase::cast(
2973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      roots_[RootIndexForEmptyFixedTypedArray(map->elements_kind())]);
2974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateForeign(Address address,
2978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       PretenureFlag pretenure) {
2979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Statically ensure that it is safe to allocate foreigns in paged spaces.
2980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize);
2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE;
2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Foreign* result = nullptr;
2983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation = Allocate(foreign_map(), space);
2984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
2985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_foreign_address(address);
2986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateByteArray(int length, PretenureFlag pretenure) {
2991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length < 0 || length > ByteArray::kMaxLength) {
2992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
2993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = ByteArray::SizeFor(length);
2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
2997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space);
2999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(byte_array_map());
3003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ByteArray::cast(result)->set_length(length);
3004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocationResult Heap::AllocateBytecodeArray(int length,
3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             const byte* const raw_bytecodes,
3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             int frame_size,
3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             int parameter_count,
3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             FixedArray* constant_pool) {
3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (length < 0 || length > BytecodeArray::kMaxLength) {
3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Bytecode array is pretenured, so constant pool array should be to.
3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!InNewSpace(constant_pool));
3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int size = BytecodeArray::SizeFor(length);
3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!allocation.To(&result)) return allocation;
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->set_map_no_write_barrier(bytecode_array_map());
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArray* instance = BytecodeArray::cast(result);
3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  instance->set_length(length);
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  instance->set_frame_size(frame_size);
3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  instance->set_parameter_count(parameter_count);
3031109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  instance->set_interrupt_budget(interpreter::Interpreter::InterruptBudget());
3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  instance->set_constant_pool(constant_pool);
3033109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  instance->set_handler_table(empty_fixed_array());
30343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  instance->set_source_position_table(empty_byte_array());
3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CopyBytes(instance->GetFirstBytecodeAddress(), raw_bytecodes, length);
3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
30403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::CreateFillerObjectAt(Address addr, int size,
30413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                ClearRecordedSlots mode) {
3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (size == 0) return;
3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject* filler = HeapObject::FromAddress(addr);
3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (size == kPointerSize) {
3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    filler->set_map_no_write_barrier(
3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Map*>(root(kOnePointerFillerMapRootIndex)));
3047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (size == 2 * kPointerSize) {
3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    filler->set_map_no_write_barrier(
3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Map*>(root(kTwoPointerFillerMapRootIndex)));
3050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_GT(size, 2 * kPointerSize);
3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    filler->set_map_no_write_barrier(
3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Map*>(root(kFreeSpaceMapRootIndex)));
3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FreeSpace::cast(filler)->nobarrier_set_size(size);
3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
30563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (mode == ClearRecordedSlots::kYes) {
30573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ClearRecordedSlotRange(addr, addr + size);
30583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // At this point, we may be deserializing the heap from a snapshot, and
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // none of the maps have been created yet and are NULL.
3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((filler->map() == NULL && !deserialization_complete_) ||
3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         filler->map()->IsMap());
3063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CanMoveObjectStart(HeapObject* object) {
3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!FLAG_move_object_start) return false;
3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3069109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Sampling heap profiler may have a reference to the object.
3070109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (isolate()->heap_profiler()->is_sampling_allocations()) return false;
3071109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address address = object->address();
3073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lo_space()->Contains(object)) return false;
3075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Page* page = Page::FromAddress(address);
3077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We can move the object start if:
3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // (1) the object is not in old space,
3079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (2) the page of the object was already swept,
3080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (3) the page was already concurrently swept. This case is an optimization
3081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for concurrent sweeping. The WasSwept predicate for concurrently swept
3082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // pages is set after sweeping all pages.
3083109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return !InOldSpace(object) || page->SweepingDone();
3084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AdjustLiveBytes(HeapObject* object, int by, InvocationMode mode) {
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // As long as the inspected object is black and we are currently not iterating
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the heap using HeapIterator, we can update the live byte count. We cannot
3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // update while using HeapIterator because the iterator is temporarily
3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // marking the whole object graph, without updating live bytes.
30923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (lo_space()->Contains(object)) {
30933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    lo_space()->AdjustLiveBytes(by);
30943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (!in_heap_iterator() &&
30953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             !mark_compact_collector()->sweeping_in_progress() &&
30963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             Marking::IsBlack(Marking::MarkBitFrom(object->address()))) {
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (mode == SEQUENTIAL_TO_SWEEPER) {
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MemoryChunk::IncrementLiveBytesFromGC(object, by);
3099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MemoryChunk::IncrementLiveBytesFromMutator(object, by);
3101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object,
3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         int elements_to_trim) {
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!object->IsFixedTypedArrayBase());
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!object->IsByteArray());
3110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize;
3111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int bytes_to_trim = elements_to_trim * element_size;
3112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = object->map();
3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For now this trick is only applied to objects in new and paged space.
3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // In large object space the object's start must coincide with chunk
3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and thus the trick is just not applicable.
3117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!lo_space()->Contains(object));
3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(object->map() != fixed_cow_array_map());
3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FixedArrayBase::kMapOffset == 0);
3121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize);
3122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize);
3123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int len = object->length();
3125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(elements_to_trim <= len);
3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Calculate location of new array start.
3128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address new_start = object->address() + bytes_to_trim;
3129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Technically in new space this write might be omitted (except for
3131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // debug mode which iterates through the heap), but to play safer
3132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we still do it.
31333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CreateFillerObjectAt(object->address(), bytes_to_trim,
31343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                       ClearRecordedSlots::kYes);
3135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize header of the trimmed array. Since left trimming is only
3136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // performed on pages which are not concurrently swept creating a filler
3137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // object does not require synchronization.
3138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(CanMoveObjectStart(object));
3139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** former_start = HeapObject::RawField(object, 0);
3140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int new_start_index = elements_to_trim * (element_size / kPointerSize);
3141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  former_start[new_start_index] = map;
3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim);
3143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArrayBase* new_object =
3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FixedArrayBase::cast(HeapObject::FromAddress(new_start));
3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3146bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Remove recorded slots for the new map and length offset.
3147bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ClearRecordedSlot(new_object, HeapObject::RawField(new_object, 0));
3148bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ClearRecordedSlot(new_object, HeapObject::RawField(
3149bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                    new_object, FixedArrayBase::kLengthOffset));
3150bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
3151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Maintain consistency of live bytes during incremental marking
3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Marking::TransferMark(this, object->address(), new_start);
3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AdjustLiveBytes(new_object, -bytes_to_trim, Heap::CONCURRENT_TO_SWEEPER);
3154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Notify the heap profiler of change in object layout.
3156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OnMoveEvent(new_object, object, new_object->Size());
3157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_object;
3158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Force instantiation of templatized method.
3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate void Heap::RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(
3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedArrayBase*, int);
3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate void Heap::RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedArrayBase*, int);
3166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<Heap::InvocationMode mode>
3169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) {
3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int len = object->length();
3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LE(elements_to_trim, len);
3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_GE(elements_to_trim, 0);
3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int bytes_to_trim;
3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (object->IsFixedTypedArrayBase()) {
3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstanceType type = object->map()->instance_type();
3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bytes_to_trim =
3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FixedTypedArrayBase::TypedArraySize(type, len) -
3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FixedTypedArrayBase::TypedArraySize(type, len - elements_to_trim);
3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (object->IsByteArray()) {
3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int new_size = ByteArray::SizeFor(len - elements_to_trim);
3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bytes_to_trim = ByteArray::SizeFor(len) - new_size;
3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_GE(bytes_to_trim, 0);
3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int element_size =
3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        object->IsFixedArray() ? kPointerSize : kDoubleSize;
3187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bytes_to_trim = elements_to_trim * element_size;
3188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For now this trick is only applied to objects in new and paged space.
3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(object->map() != fixed_cow_array_map());
3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (bytes_to_trim == 0) {
3195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // No need to create filler and update live bytes counters, just initialize
3196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // header of the trimmed array.
3197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    object->synchronized_set_length(len - elements_to_trim);
3198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Calculate location of new array end.
3202109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Address old_end = object->address() + object->Size();
3203109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Address new_end = old_end - bytes_to_trim;
3204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Technically in new space this write might be omitted (except for
3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // debug mode which iterates through the heap), but to play safer
3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we still do it.
3208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not create a filler for objects in large object space.
3209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(hpayer): We should shrink the large object page if the size
3210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of the object changed significantly.
3211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!lo_space()->Contains(object)) {
32123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CreateFillerObjectAt(new_end, bytes_to_trim, ClearRecordedSlots::kYes);
3213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize header of the trimmed array. We are storing the new length
3216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // using release store after creating a filler for the left-over space to
3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // avoid races with the sweeper thread.
3218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object->synchronized_set_length(len - elements_to_trim);
3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Maintain consistency of live bytes during incremental marking
3221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AdjustLiveBytes(object, -bytes_to_trim, mode);
3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Notify the heap profiler of change in object layout. The array may not be
3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // moved during GC, and size has to be adjusted nevertheless.
3225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapProfiler* profiler = isolate()->heap_profiler();
3226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (profiler->is_tracking_allocations()) {
3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    profiler->UpdateObjectSizeEvent(object->address(), object->Size());
3228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocationResult Heap::AllocateFixedTypedArrayWithExternalPointer(
3233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int length, ExternalArrayType array_type, void* external_pointer,
3234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PretenureFlag pretenure) {
3235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int size = FixedTypedArrayBase::kHeaderSize;
3236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space);
3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->set_map_no_write_barrier(MapForFixedTypedArray(array_type));
3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(result);
3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  elements->set_base_pointer(Smi::FromInt(0), SKIP_WRITE_BARRIER);
3246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  elements->set_external_pointer(external_pointer, SKIP_WRITE_BARRIER);
3247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  elements->set_length(length);
3248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return elements;
3249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ForFixedTypedArray(ExternalArrayType array_type, int* element_size,
3252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               ElementsKind* element_kind) {
3253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (array_type) {
3254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
3255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case kExternal##Type##Array:                          \
3256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *element_size = size;                               \
3257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *element_kind = TYPE##_ELEMENTS;                    \
3258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
3259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(TYPED_ARRAY_CASE)
3261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef TYPED_ARRAY_CASE
3262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
3264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *element_size = 0;               // Bogus
3265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *element_kind = UINT8_ELEMENTS;  // Bogus
3266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
3267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFixedTypedArray(int length,
3272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               ExternalArrayType array_type,
3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               bool initialize,
3274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               PretenureFlag pretenure) {
3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int element_size;
3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ElementsKind elements_kind;
3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ForFixedTypedArray(array_type, &element_size, &elements_kind);
3278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = OBJECT_POINTER_ALIGN(length * element_size +
3279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  FixedTypedArrayBase::kDataOffset);
3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* object = nullptr;
3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(
3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size, space,
3285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array_type == kExternalFloat64Array ? kDoubleAligned : kWordAligned);
3286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&object)) return allocation;
3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  object->set_map_no_write_barrier(MapForFixedTypedArray(array_type));
3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object);
3290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  elements->set_base_pointer(elements, SKIP_WRITE_BARRIER);
3291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  elements->set_external_pointer(
3292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ExternalReference::fixed_typed_array_base_data_offset().address(),
3293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SKIP_WRITE_BARRIER);
3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  elements->set_length(length);
3295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (initialize) memset(elements->DataPtr(), 0, elements->DataSize());
3296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return elements;
3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateCode(int object_size, bool immovable) {
3301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment));
3302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(object_size, CODE_SPACE);
3303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
3306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (immovable) {
3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Address address = result->address();
3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Code objects which should stay at a fixed address are allocated either
3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // in the first page of code space (objects on the first page of each space
3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // are never moved) or in large object space.
3311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!code_space_->FirstPage()->Contains(address) &&
3312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        MemoryChunk::FromAddress(address)->owner()->identity() != LO_SPACE) {
3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Discard the first code allocation, which was on a page where it could
3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // be moved.
33153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CreateFillerObjectAt(result->address(), object_size,
33163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           ClearRecordedSlots::kNo);
3317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE);
3318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!allocation.To(&result)) return allocation;
3319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      OnAllocationEvent(result, object_size);
3320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(code_map());
3324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* code = Code::cast(result);
3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsAligned(bit_cast<intptr_t>(code->address()), kCodeAlignment));
3326bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(memory_allocator()->code_range() == NULL ||
3327bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         !memory_allocator()->code_range()->valid() ||
3328bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         memory_allocator()->code_range()->contains(code->address()) ||
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         object_size <= code_space()->AreaSize());
3330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code->set_gc_metadata(Smi::FromInt(0));
3331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code->set_ic_age(global_ic_age_);
3332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return code;
3333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyCode(Code* code) {
3337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation;
3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate an object the same size as the code object.
3341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int obj_size = code->Size();
3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  allocation = AllocateRaw(obj_size, CODE_SPACE);
3343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
3344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy code object.
3346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address old_addr = code->address();
3347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address new_addr = result->address();
3348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CopyBlock(new_addr, old_addr, obj_size);
3349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* new_code = Code::cast(result);
3350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Relocate the copy.
3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsAligned(bit_cast<intptr_t>(new_code->address()), kCodeAlignment));
3353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(memory_allocator()->code_range() == NULL ||
3354bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         !memory_allocator()->code_range()->valid() ||
3355bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         memory_allocator()->code_range()->contains(code->address()) ||
3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         obj_size <= code_space()->AreaSize());
3357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_code->Relocate(new_addr - old_addr);
33583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // We have to iterate over the object and process its pointers when black
33593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // allocation is on.
33603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  incremental_marking()->IterateBlackObject(new_code);
3361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_code;
3362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochAllocationResult Heap::CopyBytecodeArray(BytecodeArray* bytecode_array) {
3365109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int size = BytecodeArray::SizeFor(bytecode_array->length());
3366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HeapObject* result = nullptr;
3367109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  {
3368109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
3369109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!allocation.To(&result)) return allocation;
3370109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3371109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3372109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  result->set_map_no_write_barrier(bytecode_array_map());
3373109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArray* copy = BytecodeArray::cast(result);
3374109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_length(bytecode_array->length());
3375109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_frame_size(bytecode_array->frame_size());
3376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_parameter_count(bytecode_array->parameter_count());
3377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_constant_pool(bytecode_array->constant_pool());
3378109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_handler_table(bytecode_array->handler_table());
3379109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  copy->set_source_position_table(bytecode_array->source_position_table());
33803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  copy->set_interrupt_budget(bytecode_array->interrupt_budget());
3381109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bytecode_array->CopyBytecodesTo(copy);
3382109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return copy;
3383109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
3384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyCode(Code* code, Vector<byte> reloc_info) {
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate ByteArray before the Code object, so that we do not risk
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // leaving uninitialized Code object (and breaking the heap).
3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ByteArray* reloc_info_array = nullptr;
3389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation =
3391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        AllocateByteArray(reloc_info.length(), TENURED);
3392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&reloc_info_array)) return allocation;
3393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment);
3396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int new_obj_size = Code::SizeFor(new_body_size);
3398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address old_addr = code->address();
3400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t relocation_offset =
3402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<size_t>(code->instruction_end() - old_addr);
3403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(new_obj_size, CODE_SPACE);
3406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
3407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy code object.
3409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address new_addr = result->address();
3410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy header and instructions.
3412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CopyBytes(new_addr, old_addr, relocation_offset);
3413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* new_code = Code::cast(result);
3415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_code->set_relocation_info(reloc_info_array);
3416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy patched rinfo.
3418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CopyBytes(new_code->relocation_start(), reloc_info.start(),
3419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            static_cast<size_t>(reloc_info.length()));
3420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Relocate the copy.
3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsAligned(bit_cast<intptr_t>(new_code->address()), kCodeAlignment));
3423bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(memory_allocator()->code_range() == NULL ||
3424bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         !memory_allocator()->code_range()->valid() ||
3425bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         memory_allocator()->code_range()->contains(code->address()) ||
3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         new_obj_size <= code_space()->AreaSize());
3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_code->Relocate(new_addr - old_addr);
34293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // We have to iterate over over the object and process its pointers when
34303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // black allocation is on.
34313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  incremental_marking()->IterateBlackObject(new_code);
3432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
3433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) code->ObjectVerify();
3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
3435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_code;
3436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::InitializeAllocationMemento(AllocationMemento* memento,
3440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       AllocationSite* allocation_site) {
3441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  memento->set_map_no_write_barrier(allocation_memento_map());
3442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(allocation_site->map() == allocation_site_map());
3443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER);
3444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_allocation_site_pretenuring) {
3445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocation_site->IncrementMementoCreateCount();
3446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::Allocate(Map* map, AllocationSpace space,
3451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                AllocationSite* allocation_site) {
3452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(gc_state_ == NOT_IN_GC);
3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(map->instance_type() != MAP_TYPE);
3454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = map->instance_size();
3455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (allocation_site != NULL) {
3456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size += AllocationMemento::kSize;
3457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(size, space);
3460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
3461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No need for write barrier since object is white and map is in old space.
3462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(map);
3463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (allocation_site != NULL) {
3464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
3465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<Address>(result) + map->instance_size());
3466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InitializeAllocationMemento(alloc_memento, allocation_site);
3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::InitializeJSObjectFromMap(JSObject* obj, FixedArray* properties,
3473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Map* map) {
3474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_properties(properties);
3475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->initialize_elements();
3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(1240798): Initialize the object's body using valid initial values
3477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // according to the object's initial map.  For example, if the map's
3478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instance type is JS_ARRAY_TYPE, the length field should be initialized
3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to a number (e.g. Smi::FromInt(0)) and the elements initialized to a
3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // fixed array (e.g. Heap::empty_fixed_array()).  Currently, the object
3481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // verification code has to cope with (temporarily) invalid objects.  See
3482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for example, JSArray::JSArrayVerify).
3483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InitializeJSObjectBody(obj, map, JSObject::kHeaderSize);
3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::InitializeJSObjectBody(JSObject* obj, Map* map, int start_offset) {
3488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (start_offset == map->instance_size()) return;
3489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LT(start_offset, map->instance_size());
3490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We cannot always fill with one_pointer_filler_map because objects
3492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // created from API functions expect their internal fields to be initialized
3493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // with undefined_value.
3494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Pre-allocated fields need to be initialized with undefined_value as well
3495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // so that object accesses before the constructor completes (e.g. in the
3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // debugger) will not cause a crash.
3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // In case of Array subclassing the |map| could already be transitioned
3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to different elements kind from the initial map on which we track slack.
3500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool in_progress = map->IsInobjectSlackTrackingInProgress();
3501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Object* filler;
3502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (in_progress) {
3503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    filler = one_pointer_filler_map();
3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    filler = undefined_value();
3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  obj->InitializeBody(map, start_offset, Heap::undefined_value(), filler);
3508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (in_progress) {
3509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    map->FindRootMap()->InobjectSlackTrackingStep();
3510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateJSObjectFromMap(
3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Map* map, PretenureFlag pretenure, AllocationSite* allocation_site) {
3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // JSFunctions should be allocated using AllocateFunction to be
3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // properly initialized.
3518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(map->instance_type() != JS_FUNCTION_TYPE);
3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Both types of global objects should be allocated using
3521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // AllocateGlobalObject to be properly initialized.
3522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(map->instance_type() != JS_GLOBAL_OBJECT_TYPE);
3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the backing storage for the properties.
3525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* properties = empty_fixed_array();
3526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the JSObject.
3528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSObject* js_obj = nullptr;
3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation = Allocate(map, space, allocation_site);
3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&js_obj)) return allocation;
3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize the JSObject.
3534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InitializeJSObjectFromMap(js_obj, properties, map);
3535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(js_obj->HasFastElements() || js_obj->HasFixedTypedArrayElements() ||
3536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         js_obj->HasFastStringWrapperElements());
3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return js_obj;
3538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateJSObject(JSFunction* constructor,
3542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        PretenureFlag pretenure,
3543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        AllocationSite* allocation_site) {
3544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(constructor->has_initial_map());
3545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate the object based on the constructors initial map.
3547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation = AllocateJSObjectFromMap(
3548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      constructor->initial_map(), pretenure, allocation_site);
3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
3550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Make sure result is NOT a global object if valid.
3551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!allocation.To(&obj) || !obj->IsJSGlobalObject());
3553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
3554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return allocation;
3555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
3559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Make the clone.
3560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = source->map();
3561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
35623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // We can only clone regexps, normal objects, api objects or arrays. Copying
35633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // anything else will break invariants.
3564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(map->instance_type() == JS_REGEXP_TYPE ||
3565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        map->instance_type() == JS_OBJECT_TYPE ||
35663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        map->instance_type() == JS_ARRAY_TYPE ||
3567bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        map->instance_type() == JS_API_OBJECT_TYPE ||
35683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        map->instance_type() == JS_SPECIAL_API_OBJECT_TYPE);
3569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int object_size = map->instance_size();
3571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* clone = nullptr;
3572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type()));
3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int adjusted_object_size =
3576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      site != NULL ? object_size + AllocationMemento::kSize : object_size;
3577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(adjusted_object_size, NEW_SPACE);
3578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!allocation.To(&clone)) return allocation;
3579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SLOW_DCHECK(InNewSpace(clone));
3581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Since we know the clone is allocated in new space, we can copy
3582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the contents without worrying about updating the write barrier.
3583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CopyBlock(clone->address(), source->address(), object_size);
3584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (site != NULL) {
3586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
3587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(clone) + object_size);
3588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InitializeAllocationMemento(alloc_memento, site);
3589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SLOW_DCHECK(JSObject::cast(clone)->GetElementsKind() ==
3592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              source->GetElementsKind());
3593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
3594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray* properties = FixedArray::cast(source->properties());
3595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update elements if necessary.
3596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (elements->length() > 0) {
3597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedArrayBase* elem = nullptr;
3598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
3599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllocationResult allocation;
3600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (elements->map() == fixed_cow_array_map()) {
3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        allocation = FixedArray::cast(elements);
3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (source->HasFastDoubleElements()) {
3603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        allocation = CopyFixedDoubleArray(FixedDoubleArray::cast(elements));
3604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
3605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        allocation = CopyFixedArray(FixedArray::cast(elements));
3606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!allocation.To(&elem)) return allocation;
3608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    JSObject::cast(clone)->set_elements(elem, SKIP_WRITE_BARRIER);
3610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update properties if necessary.
3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (properties->length() > 0) {
3613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedArray* prop = nullptr;
3614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
3615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllocationResult allocation = CopyFixedArray(properties);
3616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!allocation.To(&prop)) return allocation;
3617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    JSObject::cast(clone)->set_properties(prop, SKIP_WRITE_BARRIER);
3619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return the new clone.
3621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return clone;
3622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteOneByteData(Vector<const char> vector, uint8_t* chars,
3626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    int len) {
3627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Only works for one byte strings.
3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(vector.length() == len);
3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemCopy(chars, vector.start(), len);
3630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteTwoByteData(Vector<const char> vector, uint16_t* chars,
3633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    int len) {
3634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const uint8_t* stream = reinterpret_cast<const uint8_t*>(vector.start());
3635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t stream_length = vector.length();
3636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (stream_length != 0) {
3637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t consumed = 0;
3638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t c = unibrow::Utf8::ValueOf(stream, stream_length, &consumed);
3639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(c != unibrow::Utf8::kBadChar);
3640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(consumed <= stream_length);
3641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream_length -= consumed;
3642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    stream += consumed;
3643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
3644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      len -= 2;
3645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (len < 0) break;
3646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *chars++ = unibrow::Utf16::LeadSurrogate(c);
3647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *chars++ = unibrow::Utf16::TrailSurrogate(c);
3648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      len -= 1;
3650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (len < 0) break;
3651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *chars++ = c;
3652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(stream_length == 0);
3655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(len == 0);
3656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteOneByteData(String* s, uint8_t* chars, int len) {
3660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(s->length() == len);
3661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::WriteToFlat(s, chars, 0, len);
3662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void WriteTwoByteData(String* s, uint16_t* chars, int len) {
3666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(s->length() == len);
3667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::WriteToFlat(s, chars, 0, len);
3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <bool is_one_byte, typename T>
3672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateInternalizedStringImpl(T t, int chars,
3673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                      uint32_t hash_field) {
3674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(chars >= 0);
3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute map and object size.
3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size;
3677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map;
3678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_LE(0, chars);
3680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_GE(String::kMaxLength, chars);
3681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_one_byte) {
3682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    map = one_byte_internalized_string_map();
3683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size = SeqOneByteString::SizeFor(chars);
3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    map = internalized_string_map();
3686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size = SeqTwoByteString::SizeFor(chars);
3687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate string.
3690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
3693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(map);
3697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set length and hash fields of the allocated string.
3698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String* answer = String::cast(result);
3699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  answer->set_length(chars);
3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  answer->set_hash_field(hash_field);
3701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(size, answer->Size());
3703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_one_byte) {
3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    WriteOneByteData(t, SeqOneByteString::cast(answer)->GetChars(), chars);
3706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    WriteTwoByteData(t, SeqTwoByteString::cast(answer)->GetChars(), chars);
3708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return answer;
3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Need explicit instantiations.
3714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate AllocationResult Heap::AllocateInternalizedStringImpl<true>(String*,
3715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                     int,
3716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                     uint32_t);
3717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate AllocationResult Heap::AllocateInternalizedStringImpl<false>(String*,
3718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                      int,
3719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                                      uint32_t);
3720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate AllocationResult Heap::AllocateInternalizedStringImpl<false>(
3721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Vector<const char>, int, uint32_t);
3722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawOneByteString(int length,
3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                PretenureFlag pretenure) {
3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_LE(0, length);
3727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_GE(String::kMaxLength, length);
3728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = SeqOneByteString::SizeFor(length);
3729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(size <= SeqOneByteString::kMaxSize);
3730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space);
3735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partially initialize the object.
3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(one_byte_string_map());
3740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::cast(result)->set_length(length);
3741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::cast(result)->set_hash_field(String::kEmptyHashField);
3742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(size, HeapObject::cast(result)->Size());
3743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawTwoByteString(int length,
3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                PretenureFlag pretenure) {
3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_LE(0, length);
3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_GE(String::kMaxLength, length);
3752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = SeqTwoByteString::SizeFor(length);
3753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(size <= SeqTwoByteString::kMaxSize);
3754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space);
3759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partially initialize the object.
3763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(string_map());
3764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::cast(result)->set_length(length);
3765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  String::cast(result)->set_hash_field(String::kEmptyHashField);
3766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(size, HeapObject::cast(result)->Size());
3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateEmptyFixedArray() {
3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = FixedArray::SizeFor(0);
3773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, OLD_SPACE);
3776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize the object.
3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(fixed_array_map());
3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray::cast(result)->set_length(0);
3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyAndTenureFixedCOWArray(FixedArray* src) {
3786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!InNewSpace(src)) {
3787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return src;
3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int len = src->length();
3791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedArray(len, TENURED);
3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_map_no_write_barrier(fixed_array_map());
3797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray* result = FixedArray::cast(obj);
3798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_length(len);
3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy the content.
3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_gc;
3802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mvstanton): The map is set twice because of protection against calling
3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // set() on a COW FixedArray. Issue v8:3221 created to track this, and
3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we might then be able to remove this whole method.
3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject::cast(obj)->set_map_no_write_barrier(fixed_cow_array_map());
3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateEmptyFixedTypedArray(
3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ExternalArrayType array_type) {
3815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AllocateFixedTypedArray(0, array_type, false, TENURED);
3816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocationResult Heap::CopyFixedArrayAndGrow(FixedArray* src, int grow_by,
3820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             PretenureFlag pretenure) {
3821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int old_len = src->length();
3822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_len = old_len + grow_by;
3823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(new_len >= old_len);
3824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
3826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure);
3827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!allocation.To(&obj)) return allocation;
3828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3829109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  obj->set_map_no_write_barrier(fixed_array_map());
3831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FixedArray* result = FixedArray::cast(obj);
3832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->set_length(new_len);
3833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy the content.
3835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_gc;
3836109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteBarrierMode mode = obj->GetWriteBarrierMode(no_gc);
3837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < old_len; i++) result->set(i, src->get(i), mode);
3838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MemsetPointer(result->data_start() + old_len, undefined_value(), grow_by);
3839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3842109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochAllocationResult Heap::CopyFixedArrayUpTo(FixedArray* src, int new_len,
3843109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                          PretenureFlag pretenure) {
3844109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (new_len == 0) return empty_fixed_array();
3845109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3846109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_LE(new_len, src->length());
3847109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HeapObject* obj = nullptr;
3849109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  {
3850109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure);
3851109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!allocation.To(&obj)) return allocation;
3852109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3853109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  obj->set_map_no_write_barrier(fixed_array_map());
3854109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3855109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FixedArray* result = FixedArray::cast(obj);
3856109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  result->set_length(new_len);
3857109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3858109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Copy the content.
3859109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DisallowHeapAllocation no_gc;
3860109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3861109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (int i = 0; i < new_len; i++) result->set(i, src->get(i), mode);
3862109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return result;
3863109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
3866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int len = src->length();
3867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED);
3870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3872109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  obj->set_map_no_write_barrier(map);
3873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (InNewSpace(obj)) {
3874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CopyBlock(obj->address() + kPointerSize, src->address() + kPointerSize,
3875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              FixedArray::SizeFor(len) - kPointerSize);
3876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return obj;
3877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray* result = FixedArray::cast(obj);
3879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_length(len);
3880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy the content.
3882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_gc;
3883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
3885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
3886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src,
3890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                   Map* map) {
3891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int len = src->length();
3892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedDoubleArray(len, NOT_TENURED);
3895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
3896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_map_no_write_barrier(map);
3898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CopyBlock(obj->address() + FixedDoubleArray::kLengthOffset,
3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            src->address() + FixedDoubleArray::kLengthOffset,
3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset);
3901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj;
3902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawFixedArray(int length,
3906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             PretenureFlag pretenure) {
3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length < 0 || length > FixedArray::kMaxLength) {
3908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
3909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = FixedArray::SizeFor(length);
3911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AllocateRaw(size, space);
3914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFixedArrayWithFiller(int length,
3918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                    PretenureFlag pretenure,
3919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                    Object* filler) {
3920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(length >= 0);
3921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(empty_fixed_array()->IsFixedArray());
3922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length == 0) return empty_fixed_array();
3923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(filler));
3925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedArray(length, pretenure);
3928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
3929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(fixed_array_map());
3932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray* array = FixedArray::cast(result);
3933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array->set_length(length);
3934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemsetPointer(array->data_start(), filler, length);
3935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return array;
3936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
3940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return AllocateFixedArrayWithFiller(length, pretenure, undefined_value());
3941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateUninitializedFixedArray(int length) {
3945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length == 0) return empty_fixed_array();
3946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* obj = nullptr;
3948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationResult allocation = AllocateRawFixedArray(length, NOT_TENURED);
3950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&obj)) return allocation;
3951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_map_no_write_barrier(fixed_array_map());
3954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedArray::cast(obj)->set_length(length);
3955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj;
3956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateUninitializedFixedDoubleArray(
3960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int length, PretenureFlag pretenure) {
3961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length == 0) return empty_fixed_array();
3962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* elements = nullptr;
3964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationResult allocation = AllocateRawFixedDoubleArray(length, pretenure);
3965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&elements)) return allocation;
3966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  elements->set_map_no_write_barrier(fixed_double_array_map());
3968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FixedDoubleArray::cast(elements)->set_length(length);
3969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return elements;
3970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateRawFixedDoubleArray(int length,
3974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                   PretenureFlag pretenure) {
3975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length < 0 || length > FixedDoubleArray::kMaxLength) {
3976bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
3977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = FixedDoubleArray::SizeFor(length);
3979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSpace space = SelectSpace(pretenure);
3980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* object = nullptr;
3982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
3983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = AllocateRaw(size, space, kDoubleAligned);
3984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&object)) return allocation;
3985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return object;
3988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateSymbol() {
3992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Statically ensure that it is safe to allocate symbols in paged spaces.
3993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(Symbol::kSize <= Page::kMaxRegularHeapObjectSize);
3994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* result = nullptr;
3996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationResult allocation = AllocateRaw(Symbol::kSize, OLD_SPACE);
3997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!allocation.To(&result)) return allocation;
3998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->set_map_no_write_barrier(symbol_map());
4000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Generate a random hash value.
4002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int hash;
4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int attempts = 0;
4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  do {
4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    hash = isolate()->random_number_generator()->NextInt() & Name::kHashBitMask;
4006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    attempts++;
4007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (hash == 0 && attempts < 30);
4008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (hash == 0) hash = 1;  // never return 0
4009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Symbol::cast(result)
4011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ->set_hash_field(Name::kIsNotArrayIndexMask | (hash << Name::kHashShift));
4012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Symbol::cast(result)->set_name(undefined_value());
4013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Symbol::cast(result)->set_flags(0);
4014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!Symbol::cast(result)->is_private());
4016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
4017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult Heap::AllocateStruct(InstanceType type) {
4021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map;
4022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (type) {
4023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define MAKE_CASE(NAME, Name, name) \
4024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case NAME##_TYPE:                 \
4025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    map = name##_map();             \
4026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    break;
4027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STRUCT_LIST(MAKE_CASE)
4028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef MAKE_CASE
4029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
4030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
4031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return exception();
4032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = map->instance_size();
4034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Struct* result = nullptr;
4035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
4036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllocationResult allocation = Allocate(map, OLD_SPACE);
4037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!allocation.To(&result)) return allocation;
4038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->InitializeBody(size);
4040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
4041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::IsHeapIterable() {
4045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(hpayer): This function is not correct. Allocation folding in old
4046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // space breaks the iterability.
4047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new_space_top_after_last_gc_ == new_space()->top();
4048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::MakeHeapIterable() {
4052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(AllowHeapAllocation::IsAllowed());
4053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!IsHeapIterable()) {
4054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable");
4055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mark_compact_collector()->sweeping_in_progress()) {
4057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    mark_compact_collector()->EnsureSweepingCompleted();
4058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsHeapIterable());
4060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic double ComputeMutatorUtilization(double mutator_speed, double gc_speed) {
4064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double kMinMutatorUtilization = 0.0;
4065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double kConservativeGcSpeedInBytesPerMillisecond = 200000;
4066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mutator_speed == 0) return kMinMutatorUtilization;
4067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (gc_speed == 0) gc_speed = kConservativeGcSpeedInBytesPerMillisecond;
4068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Derivation:
4069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // mutator_utilization = mutator_time / (mutator_time + gc_time)
4070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // mutator_time = 1 / mutator_speed
4071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // gc_time = 1 / gc_speed
4072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // mutator_utilization = (1 / mutator_speed) /
4073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //                       (1 / mutator_speed + 1 / gc_speed)
4074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // mutator_utilization = gc_speed / (mutator_speed + gc_speed)
4075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return gc_speed / (mutator_speed + gc_speed);
4076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble Heap::YoungGenerationMutatorUtilization() {
4080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double mutator_speed = static_cast<double>(
4081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond());
40823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  double gc_speed =
40833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      tracer()->ScavengeSpeedInBytesPerMillisecond(kForSurvivedObjects);
4084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double result = ComputeMutatorUtilization(mutator_speed, gc_speed);
4085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_mutator_utilization) {
4086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintIsolate(isolate(),
4087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 "Young generation mutator utilization = %.3f ("
4088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 "mutator_speed=%.f, gc_speed=%.f)\n",
4089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 result, mutator_speed, gc_speed);
4090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
4092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble Heap::OldGenerationMutatorUtilization() {
4096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double mutator_speed = static_cast<double>(
4097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer()->OldGenerationAllocationThroughputInBytesPerMillisecond());
4098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double gc_speed = static_cast<double>(
4099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer()->CombinedMarkCompactSpeedInBytesPerMillisecond());
4100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double result = ComputeMutatorUtilization(mutator_speed, gc_speed);
4101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_mutator_utilization) {
4102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintIsolate(isolate(),
4103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 "Old generation mutator utilization = %.3f ("
4104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 "mutator_speed=%.f, gc_speed=%.f)\n",
4105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 result, mutator_speed, gc_speed);
4106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
4108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::HasLowYoungGenerationAllocationRate() {
4112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double high_mutator_utilization = 0.993;
4113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return YoungGenerationMutatorUtilization() > high_mutator_utilization;
4114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::HasLowOldGenerationAllocationRate() {
4118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double high_mutator_utilization = 0.993;
4119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return OldGenerationMutatorUtilization() > high_mutator_utilization;
4120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
4121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::HasLowAllocationRate() {
4124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HasLowYoungGenerationAllocationRate() &&
4125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         HasLowOldGenerationAllocationRate();
4126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
4127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::HasHighFragmentation() {
4130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t used = PromotedSpaceSizeOfObjects();
4131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t committed = CommittedOldGenerationMemory();
4132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HasHighFragmentation(used, committed);
4133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::HasHighFragmentation(intptr_t used, intptr_t committed) {
4137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const intptr_t kSlack = 16 * MB;
4138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Fragmentation is high if committed > 2 * used + kSlack.
4139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Rewrite the exression to avoid overflow.
4140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return committed - used > used + kSlack;
4141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4143109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid Heap::SetOptimizeForMemoryUsage() {
4144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Activate memory reducer when switching to background if
4145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // - there was no mark compact since the start.
4146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // - the committed memory can be potentially reduced.
4147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // 2 pages for the old, code, and map space + 1 page for new space.
4148109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int kMinCommittedMemory = 7 * Page::kPageSize;
4149109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory) {
4150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    MemoryReducer::Event event;
4151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    event.type = MemoryReducer::kPossibleGarbage;
4152109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    event.time_ms = MonotonicallyIncreasingTimeInMs();
4153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    memory_reducer_->NotifyPossibleGarbage(event);
4154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4155109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  optimize_for_memory_usage_ = true;
4156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
4157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ReduceNewSpaceSize() {
4159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(ulan): Unify this constant with the similar constant in
4160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // GCIdleTimeHandler once the change is merged to 4.5.
4161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const size_t kLowAllocationThroughput = 1000;
41623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const double allocation_throughput =
4163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      tracer()->CurrentAllocationThroughputInBytesPerMillisecond();
4164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_predictable) return;
4166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (ShouldReduceMemory() ||
4168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ((allocation_throughput != 0) &&
4169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       (allocation_throughput < kLowAllocationThroughput))) {
4170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_space_.Shrink();
4171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UncommitFromSpace();
4172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::FinalizeIncrementalMarkingIfComplete(const char* comment) {
4177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incremental_marking()->IsMarking() &&
4178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      (incremental_marking()->IsReadyToOverApproximateWeakClosure() ||
4179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       (!incremental_marking()->finalize_marking_completed() &&
4180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        mark_compact_collector()->marking_deque()->IsEmpty()))) {
4181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FinalizeIncrementalMarking(comment);
4182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (incremental_marking()->IsComplete() ||
4183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             (mark_compact_collector()->marking_deque()->IsEmpty())) {
4184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CollectAllGarbage(current_gc_flags_, comment);
4185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::TryFinalizeIdleIncrementalMarking(double idle_time_in_ms) {
4190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t size_of_objects = static_cast<size_t>(SizeOfObjects());
41913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  double final_incremental_mark_compact_speed_in_bytes_per_ms =
41923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond();
4193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incremental_marking()->IsReadyToOverApproximateWeakClosure() ||
4194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      (!incremental_marking()->finalize_marking_completed() &&
4195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       mark_compact_collector()->marking_deque()->IsEmpty() &&
4196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       gc_idle_time_handler_->ShouldDoOverApproximateWeakClosure(
41973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           idle_time_in_ms))) {
4198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FinalizeIncrementalMarking(
4199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        "Idle notification: finalize incremental marking");
4200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
4201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (incremental_marking()->IsComplete() ||
4202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             (mark_compact_collector()->marking_deque()->IsEmpty() &&
4203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              gc_idle_time_handler_->ShouldDoFinalIncrementalMarkCompact(
42043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  idle_time_in_ms, size_of_objects,
4205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  final_incremental_mark_compact_speed_in_bytes_per_ms))) {
4206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CollectAllGarbage(current_gc_flags_,
4207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      "idle notification: finalize incremental marking");
4208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
4209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
4211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
42133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::RegisterReservationsForBlackAllocation(Reservation* reservations) {
42143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // TODO(hpayer): We do not have to iterate reservations on black objects
42153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // for marking. We just have to execute the special visiting side effect
42163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // code that adds objects to global data structures, e.g. for array buffers.
42173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
42183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Code space, map space, and large object space do not use black pages.
42193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Hence we have to color all objects of the reservation first black to avoid
42203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // unnecessary marking deque load.
42213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (incremental_marking()->black_allocation()) {
42223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (int i = CODE_SPACE; i < Serializer::kNumberOfSpaces; i++) {
42233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      const Heap::Reservation& res = reservations[i];
42243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      for (auto& chunk : res) {
42253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Address addr = chunk.start;
42263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        while (addr < chunk.end) {
42273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          HeapObject* obj = HeapObject::FromAddress(addr);
42283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          Marking::MarkBlack(Marking::MarkBitFrom(obj));
42293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          MemoryChunk::IncrementLiveBytesFromGC(obj, obj->Size());
42303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          addr += obj->Size();
42313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
42323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
42333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
42343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (int i = OLD_SPACE; i < Serializer::kNumberOfSpaces; i++) {
42353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      const Heap::Reservation& res = reservations[i];
42363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      for (auto& chunk : res) {
42373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Address addr = chunk.start;
42383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        while (addr < chunk.end) {
42393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          HeapObject* obj = HeapObject::FromAddress(addr);
42403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          incremental_marking()->IterateBlackObject(obj);
42413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          addr += obj->Size();
42423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
42433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
42443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
42453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
42463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
4247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochGCIdleTimeHeapState Heap::ComputeHeapState() {
4249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCIdleTimeHeapState heap_state;
4250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.contexts_disposed = contexts_disposed_;
4251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  heap_state.contexts_disposal_rate =
4252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      tracer()->ContextDisposalRateInMilliseconds();
4253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects());
4254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
4255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return heap_state;
4256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::PerformIdleTimeAction(GCIdleTimeAction action,
4260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 GCIdleTimeHeapState heap_state,
4261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 double deadline_in_ms) {
4262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool result = false;
4263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (action.type) {
4264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DONE:
4265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result = true;
4266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case DO_INCREMENTAL_STEP: {
4268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (incremental_marking()->incremental_marking_job()->IdleTaskPending()) {
4269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        result = true;
4270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
4271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        incremental_marking()
4272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ->incremental_marking_job()
4273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ->NotifyIdleTaskProgress();
4274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        result = IncrementalMarkingJob::IdleTask::Step(this, deadline_in_ms) ==
4275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 IncrementalMarkingJob::IdleTask::kDone;
4276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
4277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
4279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DO_FULL_GC: {
4280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(contexts_disposed_ > 0);
4281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HistogramTimerScope scope(isolate_->counters()->gc_context());
4282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      TRACE_EVENT0("v8", "V8.GCContext");
4283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed");
4284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DO_NOTHING:
4287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
4291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::IdleNotificationEpilogue(GCIdleTimeAction action,
4295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    GCIdleTimeHeapState heap_state,
4296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    double start_ms, double deadline_in_ms) {
4297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double idle_time_in_ms = deadline_in_ms - start_ms;
4298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  double current_time = MonotonicallyIncreasingTimeInMs();
4299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  last_idle_notification_time_ = current_time;
4300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  double deadline_difference = deadline_in_ms - current_time;
4301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  contexts_disposed_ = 0;
4303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
4305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<int>(idle_time_in_ms));
4306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (deadline_in_ms - start_ms >
4308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      GCIdleTimeHandler::kMaxFrameRenderingIdleTime) {
4309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int committed_memory = static_cast<int>(CommittedMemory() / KB);
4310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int used_memory = static_cast<int>(heap_state.size_of_objects / KB);
4311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->counters()->aggregated_memory_heap_committed()->AddSample(
4312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        start_ms, committed_memory);
4313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate()->counters()->aggregated_memory_heap_used()->AddSample(
4314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        start_ms, used_memory);
4315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (deadline_difference >= 0) {
4318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (action.type != DONE && action.type != DO_NOTHING) {
4319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate()->counters()->gc_idle_time_limit_undershot()->AddSample(
4320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          static_cast<int>(deadline_difference));
4321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
4322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
4323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate()->counters()->gc_idle_time_limit_overshot()->AddSample(
4324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        static_cast<int>(-deadline_difference));
4325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if ((FLAG_trace_idle_notification && action.type > DO_NOTHING) ||
4328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FLAG_trace_idle_notification_verbose) {
4329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintIsolate(isolate_, "%8.0f ms: ", isolate()->time_millis_since_init());
4330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF(
4331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        "Idle notification: requested idle time %.2f ms, used idle time %.2f "
4332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        "ms, deadline usage %.2f ms [",
4333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        idle_time_in_ms, idle_time_in_ms - deadline_difference,
4334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        deadline_difference);
4335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    action.Print();
4336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF("]");
4337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (FLAG_trace_idle_notification_verbose) {
4338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      PrintF("[");
4339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      heap_state.Print();
4340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      PrintF("]");
4341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
4342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF("\n");
4343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble Heap::MonotonicallyIncreasingTimeInMs() {
4348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
4349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         static_cast<double>(base::Time::kMillisecondsPerSecond);
4350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::IdleNotification(int idle_time_in_ms) {
4354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return IdleNotification(
4355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() +
4356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      (static_cast<double>(idle_time_in_ms) /
4357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       static_cast<double>(base::Time::kMillisecondsPerSecond)));
4358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::IdleNotification(double deadline_in_seconds) {
4362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(HasBeenSetUp());
4363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double deadline_in_ms =
4364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      deadline_in_seconds *
4365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<double>(base::Time::kMillisecondsPerSecond);
4366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HistogramTimerScope idle_notification_scope(
4367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_->counters()->gc_idle_notification());
4368109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE_EVENT0("v8", "V8.GCIdleNotification");
4369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double start_ms = MonotonicallyIncreasingTimeInMs();
4370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double idle_time_in_ms = deadline_in_ms - start_ms;
4371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer()->SampleAllocation(start_ms, NewSpaceAllocationCounter(),
4373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             OldGenerationAllocationCounter());
4374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCIdleTimeHeapState heap_state = ComputeHeapState();
4376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCIdleTimeAction action =
4378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      gc_idle_time_handler_->Compute(idle_time_in_ms, heap_state);
4379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms);
4381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IdleNotificationEpilogue(action, heap_state, start_ms, deadline_in_ms);
4383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
4384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Heap::RecentIdleNotificationHappened() {
4388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return (last_idle_notification_time_ +
4389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          GCIdleTimeHandler::kMaxScheduledIdleTime) >
4390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         MonotonicallyIncreasingTimeInMs();
4391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
4392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
43933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochclass MemoryPressureInterruptTask : public CancelableTask {
43943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch public:
43953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  explicit MemoryPressureInterruptTask(Heap* heap)
43963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      : CancelableTask(heap->isolate()), heap_(heap) {}
43973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
43983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  virtual ~MemoryPressureInterruptTask() {}
43993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
44003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch private:
44013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // v8::internal::CancelableTask overrides.
44023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void RunInternal() override { heap_->CheckMemoryPressure(); }
44033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
44043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Heap* heap_;
44053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(MemoryPressureInterruptTask);
44063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch};
44073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
44083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::CheckMemoryPressure() {
44093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (memory_pressure_level_.Value() == MemoryPressureLevel::kCritical) {
44103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CollectGarbageOnMemoryPressure("memory pressure");
44113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (memory_pressure_level_.Value() == MemoryPressureLevel::kModerate) {
44123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (FLAG_incremental_marking && incremental_marking()->IsStopped()) {
44133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      StartIdleIncrementalMarking();
44143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
44153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
44163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  MemoryReducer::Event event;
44173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  event.type = MemoryReducer::kPossibleGarbage;
44183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  event.time_ms = MonotonicallyIncreasingTimeInMs();
44193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  memory_reducer_->NotifyPossibleGarbage(event);
44203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
44213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
44223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::CollectGarbageOnMemoryPressure(const char* source) {
44233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CollectAllGarbage(kReduceMemoryFootprintMask | kAbortIncrementalMarkingMask,
44243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                    source);
44253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
44263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
44273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::MemoryPressureNotification(MemoryPressureLevel level,
44283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                      bool is_isolate_locked) {
44293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  MemoryPressureLevel previous = memory_pressure_level_.Value();
44303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  memory_pressure_level_.SetValue(level);
44313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if ((previous != MemoryPressureLevel::kCritical &&
44323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch       level == MemoryPressureLevel::kCritical) ||
44333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      (previous == MemoryPressureLevel::kNone &&
44343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch       level == MemoryPressureLevel::kModerate)) {
44353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (is_isolate_locked) {
44363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CheckMemoryPressure();
44373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else {
44383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ExecutionAccess access(isolate());
44393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      isolate()->stack_guard()->RequestGC();
44403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      V8::GetCurrentPlatform()->CallOnForegroundThread(
44413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          reinterpret_cast<v8::Isolate*>(isolate()),
44423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          new MemoryPressureInterruptTask(this));
44433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
44443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
44453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
4446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
4448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::Print() {
4450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return;
4451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate()->PrintStack(stdout);
4452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllSpaces spaces(this);
4453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
4454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    space->Print();
4455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportCodeStatistics(const char* title) {
4460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF(">>>>>> Code Stats (%s) >>>>>>\n", title);
4461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PagedSpace::ResetCodeStatistics(isolate());
4462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not look for code in new space, map space, or old space.  If code
4463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // somehow ends up in those spaces, we would miss it here.
4464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_space_->CollectCodeStatistics();
4465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  lo_space_->CollectCodeStatistics();
4466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PagedSpace::ReportCodeStatistics(isolate());
4467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This function expects that NewSpace's allocated objects histogram is
4471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// populated (via a call to CollectStatistics or else as a side effect of a
4472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// just-completed scavenge collection).
4473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ReportHeapStatistics(const char* title) {
4474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  USE(title);
4475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF(">>>>>> =============== %s (%d) =============== >>>>>>\n", title,
4476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         gc_count_);
4477bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrintF("old_generation_allocation_limit_ %" V8PRIdPTR "\n",
4478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         old_generation_allocation_limit_);
4479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("\n");
4481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles(isolate_));
4482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->global_handles()->PrintStats();
4483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("\n");
4484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Heap statistics : ");
4486bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  memory_allocator()->ReportStatistics();
4487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("To space : ");
4488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_.ReportStatistics();
4489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintF("Old space : ");
4490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  old_space_->ReportStatistics();
4491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Code space : ");
4492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_space_->ReportStatistics();
4493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Map space : ");
4494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map_space_->ReportStatistics();
4495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Large object space : ");
4496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  lo_space_->ReportStatistics();
4497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF(">>>>>> ========================================= >>>>>>\n");
4498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
4501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool Heap::Contains(HeapObject* value) {
4503bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (memory_allocator()->IsOutsideAllocatedSpace(value->address())) {
4504109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return false;
4505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
45068389745919cae02139ddc085a63c00d024269cf2Ben Murdoch  return HasBeenSetUp() &&
4507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         (new_space_.ToSpaceContains(value) || old_space_->Contains(value) ||
4508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          code_space_->Contains(value) || map_space_->Contains(value) ||
4509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          lo_space_->Contains(value));
45108389745919cae02139ddc085a63c00d024269cf2Ben Murdoch}
4511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool Heap::ContainsSlow(Address addr) {
4513bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (memory_allocator()->IsOutsideAllocatedSpace(addr)) {
4514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return false;
4515109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4516109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return HasBeenSetUp() &&
4517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         (new_space_.ToSpaceContainsSlow(addr) ||
4518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          old_space_->ContainsSlow(addr) || code_space_->ContainsSlow(addr) ||
4519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          map_space_->ContainsSlow(addr) || lo_space_->ContainsSlow(addr));
4520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
4521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4522f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdochbool Heap::InSpace(HeapObject* value, AllocationSpace space) {
4523bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (memory_allocator()->IsOutsideAllocatedSpace(value->address())) {
4524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return false;
4525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!HasBeenSetUp()) return false;
4527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  switch (space) {
4529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case NEW_SPACE:
4530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return new_space_.ToSpaceContains(value);
4531109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case OLD_SPACE:
4532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return old_space_->Contains(value);
4533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case CODE_SPACE:
4534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return code_space_->Contains(value);
4535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MAP_SPACE:
4536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return map_space_->Contains(value);
4537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case LO_SPACE:
4538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return lo_space_->Contains(value);
4539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  UNREACHABLE();
4541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return false;
4542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
4543f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
4544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool Heap::InSpaceSlow(Address addr, AllocationSpace space) {
4545bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (memory_allocator()->IsOutsideAllocatedSpace(addr)) {
4546109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return false;
4547109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasBeenSetUp()) return false;
4549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (space) {
4551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NEW_SPACE:
4552109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return new_space_.ToSpaceContainsSlow(addr);
4553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
4554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return old_space_->ContainsSlow(addr);
4555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_SPACE:
4556109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return code_space_->ContainsSlow(addr);
4557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case MAP_SPACE:
4558109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return map_space_->ContainsSlow(addr);
4559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LO_SPACE:
4560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return lo_space_->ContainsSlow(addr);
4561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
4564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::IsValidAllocationSpace(AllocationSpace space) {
4568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (space) {
4569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case NEW_SPACE:
4570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
4571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CODE_SPACE:
4572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MAP_SPACE:
4573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case LO_SPACE:
4574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
4575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
4576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
4577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool Heap::RootIsImmortalImmovable(int root_index) {
4582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  switch (root_index) {
4583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define IMMORTAL_IMMOVABLE_ROOT(name) case Heap::k##name##RootIndex:
4584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
4585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef IMMORTAL_IMMOVABLE_ROOT
4586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define INTERNALIZED_STRING(name, value) case Heap::k##name##RootIndex:
4587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    INTERNALIZED_STRING_LIST(INTERNALIZED_STRING)
4588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef INTERNALIZED_STRING
4589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define STRING_TYPE(NAME, size, name, Name) case Heap::k##Name##MapRootIndex:
4590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    STRING_TYPE_LIST(STRING_TYPE)
4591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef STRING_TYPE
4592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return true;
4593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    default:
4594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return false;
4595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
4596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
4597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
4600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::Verify() {
4601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(HasBeenSetUp());
4602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(isolate());
4603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mark_compact_collector()->sweeping_in_progress()) {
4605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We have to wait here for the sweeper threads to have an iterable heap.
4606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    mark_compact_collector()->EnsureSweepingCompleted();
4607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VerifyPointersVisitor visitor;
4610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateRoots(&visitor, VISIT_ONLY_STRONG);
4611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VerifySmisVisitor smis_visitor;
4613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateSmiRoots(&smis_visitor);
4614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_.Verify();
4616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  old_space_->Verify(&visitor);
4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  map_space_->Verify(&visitor);
4619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VerifyPointersVisitor no_dirty_regions_visitor;
4621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_space_->Verify(&no_dirty_regions_visitor);
4622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  lo_space_->Verify();
4624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mark_compact_collector()->VerifyWeakEmbeddedObjectsInCode();
4626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_omit_map_checks_for_leaf_maps) {
4627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    mark_compact_collector()->VerifyOmittedMapChecks();
4628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
4631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::ZapFromSpace() {
4634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!new_space_.IsFromSpaceCommitted()) return;
4635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NewSpacePageIterator it(new_space_.FromSpaceStart(),
4636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          new_space_.FromSpaceEnd());
4637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (it.has_next()) {
4638bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Page* page = it.next();
4639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Address cursor = page->area_start(), limit = page->area_end();
4640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         cursor < limit; cursor += kPointerSize) {
4641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Memory::Address_at(cursor) = kFromSpaceZapValue;
4642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::IteratePromotedObjectPointers(HeapObject* object, Address start,
46473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                         Address end, bool record_slots,
46483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                         ObjectSlotCallback callback) {
4649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address slot_address = start;
4650109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Page* page = Page::FromAddress(start);
4651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (slot_address < end) {
4653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** slot = reinterpret_cast<Object**>(slot_address);
4654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object* target = *slot;
4655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (target->IsHeapObject()) {
4656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (Heap::InFromSpace(target)) {
4657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        callback(reinterpret_cast<HeapObject**>(slot),
4658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 HeapObject::cast(target));
4659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Object* new_target = *slot;
4660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (InNewSpace(new_target)) {
4661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SLOW_DCHECK(Heap::InToSpace(new_target));
4662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          SLOW_DCHECK(new_target->IsHeapObject());
4663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          RememberedSet<OLD_TO_NEW>::Insert(page, slot_address);
4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
4665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SLOW_DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_target));
4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (record_slots &&
4667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 MarkCompactCollector::IsOnEvacuationCandidate(target)) {
4668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        mark_compact_collector()->RecordSlot(object, slot, target);
4669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    slot_address += kPointerSize;
4672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochclass IteratePromotedObjectsVisitor final : public ObjectVisitor {
4676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
46773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  IteratePromotedObjectsVisitor(Heap* heap, HeapObject* target,
46783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                bool record_slots, ObjectSlotCallback callback)
4679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : heap_(heap),
4680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        target_(target),
4681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        record_slots_(record_slots),
4682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        callback_(callback) {}
4683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V8_INLINE void VisitPointers(Object** start, Object** end) override {
46853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    heap_->IteratePromotedObjectPointers(
4686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        target_, reinterpret_cast<Address>(start),
4687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        reinterpret_cast<Address>(end), record_slots_, callback_);
4688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  V8_INLINE void VisitCodeEntry(Address code_entry_slot) override {
46913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Black allocation requires us to process objects referenced by
46923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // promoted objects.
46933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (heap_->incremental_marking()->black_allocation()) {
46943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot));
46953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      IncrementalMarking::MarkObject(heap_, code);
46963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
46973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
4698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
4700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Heap* heap_;
4701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObject* target_;
4702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool record_slots_;
4703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ObjectSlotCallback callback_;
4704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
4705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::IteratePromotedObject(HeapObject* target, int size,
47073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 bool was_marked_black,
47083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 ObjectSlotCallback callback) {
4709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We are not collecting slots on new space objects during mutation
4710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // thus we have to scan for pointers to evacuation candidates when we
4711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // promote objects. But we should not record any slots in non-black
4712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // objects. Grey object's slots would be rescanned.
4713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // White object might not survive until the end of collection
4714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it would be a violation of the invariant to record it's slots.
4715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool record_slots = false;
4716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (incremental_marking()->IsCompacting()) {
4717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MarkBit mark_bit = Marking::MarkBitFrom(target);
4718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    record_slots = Marking::IsBlack(mark_bit);
4719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  IteratePromotedObjectsVisitor visitor(this, target, record_slots, callback);
4722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  target->IterateBody(target->map()->instance_type(), size, &visitor);
47233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
47243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // When black allocations is on, we have to visit not already marked black
47253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // objects (in new space) promoted to black pages to keep their references
47263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // alive.
47273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // TODO(hpayer): Implement a special promotion visitor that incorporates
47283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // regular visiting and IteratePromotedObjectPointers.
47293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!was_marked_black) {
47303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (incremental_marking()->black_allocation()) {
47313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      IncrementalMarking::MarkObject(this, target->map());
47323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      incremental_marking()->IterateBlackObject(target);
47333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
47343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
4735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) {
4739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateStrongRoots(v, mode);
4740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateWeakRoots(v, mode);
4741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) {
4745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->VisitPointer(reinterpret_cast<Object**>(&roots_[kStringTableRootIndex]));
4746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kStringTable);
4747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode != VISIT_ALL_IN_SCAVENGE && mode != VISIT_ALL_IN_SWEEP_NEWSPACE) {
4748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Scavenge collections have special processing for this.
4749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    external_string_table_.Iterate(v);
4750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kExternalStringsTable);
4752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateSmiRoots(ObjectVisitor* v) {
4756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Acquire execution access since we are going to read stack limit values.
4757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExecutionAccess access(isolate());
4758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->VisitPointers(&roots_[kSmiRootsStart], &roots_[kRootListLength]);
4759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kSmiRootList);
4760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4762bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// We cannot avoid stale handles to left-trimmed objects, but can only make
4763bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// sure all handles still needed are updated. Filter out a stale pointer
4764bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// and clear the slot to allow post processing of handles (needed because
4765bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// the sweeper might actually free the underlying page).
4766bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass FixStaleLeftTrimmedHandlesVisitor : public ObjectVisitor {
4767bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch public:
4768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  explicit FixStaleLeftTrimmedHandlesVisitor(Heap* heap) : heap_(heap) {
4769bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    USE(heap_);
4770bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
4771bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4772bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void VisitPointer(Object** p) override { FixHandle(p); }
4773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4774bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
4775bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    for (Object** p = start; p < end; p++) FixHandle(p);
4776bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
4777bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4778bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch private:
4779bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  inline void FixHandle(Object** p) {
4780bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    HeapObject* current = reinterpret_cast<HeapObject*>(*p);
4781bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!current->IsHeapObject()) return;
4782bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    const MapWord map_word = current->map_word();
4783bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!map_word.IsForwardingAddress() && current->IsFiller()) {
4784bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#ifdef DEBUG
4785bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      // We need to find a FixedArrayBase map after walking the fillers.
4786bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      while (current->IsFiller()) {
4787bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        Address next = reinterpret_cast<Address>(current);
4788bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (current->map() == heap_->one_pointer_filler_map()) {
4789bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          next += kPointerSize;
4790bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        } else if (current->map() == heap_->two_pointer_filler_map()) {
4791bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          next += 2 * kPointerSize;
4792bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        } else {
4793bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          next += current->Size();
4794bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        }
4795bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        current = reinterpret_cast<HeapObject*>(next);
4796bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
4797bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      DCHECK(current->IsFixedArrayBase());
4798bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#endif  // DEBUG
4799bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      *p = nullptr;
4800bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
4801bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
4802bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
4803bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Heap* heap_;
4804bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch};
4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
4807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
4808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kStrongRootList);
48093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The serializer/deserializer iterates the root list twice, first to pick
48103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // off immortal immovable roots to make sure they end up on the first page,
48113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // and then again for the rest.
48123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (mode == VISIT_ONLY_STRONG_ROOT_LIST) return;
4813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->bootstrapper()->Iterate(v);
4815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kBootstrapper);
4816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->Iterate(v);
4817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kTop);
4818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Relocatable::Iterate(isolate_, v);
4819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kRelocatable);
4820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->compilation_cache()->Iterate(v);
4822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kCompilationCache);
4823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over local handles in handle scopes.
4825bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FixStaleLeftTrimmedHandlesVisitor left_trim_visitor(this);
4826bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  isolate_->handle_scope_implementer()->Iterate(&left_trim_visitor);
4827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->handle_scope_implementer()->Iterate(v);
4828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->IterateDeferredHandles(v);
4829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kHandleScope);
4830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over the builtin code objects and code stubs in the
4832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // heap. Note that it is not necessary to iterate over code objects
4833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // on scavenge collections.
4834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode != VISIT_ALL_IN_SCAVENGE) {
4835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->builtins()->IterateBuiltins(v);
4836109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    v->Synchronize(VisitorSynchronization::kBuiltins);
4837109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    isolate_->interpreter()->IterateDispatchTable(v);
4838109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    v->Synchronize(VisitorSynchronization::kDispatchTable);
4839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over global handles.
4842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (mode) {
48433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case VISIT_ONLY_STRONG_ROOT_LIST:
48443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      UNREACHABLE();
48453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
4846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VISIT_ONLY_STRONG:
48473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case VISIT_ONLY_STRONG_FOR_SERIALIZATION:
4848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->global_handles()->IterateStrongRoots(v);
4849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VISIT_ALL_IN_SCAVENGE:
4851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v);
4852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VISIT_ALL_IN_SWEEP_NEWSPACE:
4854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VISIT_ALL:
4855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->global_handles()->IterateAllRoots(v);
4856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kGlobalHandles);
4859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over eternal handles.
4861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == VISIT_ALL_IN_SCAVENGE) {
4862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->eternal_handles()->IterateNewSpaceRoots(v);
4863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
4864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->eternal_handles()->IterateAllRoots(v);
4865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kEternalHandles);
4867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over pointers being held by inactive threads.
4869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->thread_manager()->Iterate(v);
4870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->Synchronize(VisitorSynchronization::kThreadManager);
4871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Iterate over other strong roots (currently only identity maps).
4873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (StrongRootsList* list = strong_roots_list_; list; list = list->next) {
4874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    v->VisitPointers(list->start, list->end);
4875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  v->Synchronize(VisitorSynchronization::kStrongRoots);
4877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
48783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Iterate over the partial snapshot cache unless serializing.
48793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (mode != VISIT_ONLY_STRONG_FOR_SERIALIZATION) {
48803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    SerializerDeserializer::Iterate(isolate_, v);
48813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
4882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We don't do a v->Synchronize call here, because in debug mode that will
4883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // output a flag to the snapshot.  However at this point the serializer and
4884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deserializer are deliberately a little unsynchronized (see above) so the
4885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // checking of the sync flag in the snapshot would fail.
4886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(1236194): Since the heap size is configurable on the command line
4890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and through the API, we should gracefully handle the case that the heap
4891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// size is not big enough to fit all the initial objects.
4892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::ConfigureHeap(int max_semi_space_size, int max_old_space_size,
4893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         int max_executable_size, size_t code_range_size) {
4894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HasBeenSetUp()) return false;
4895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Overwrite default configuration.
4897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (max_semi_space_size > 0) {
4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    max_semi_space_size_ = max_semi_space_size * MB;
4899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (max_old_space_size > 0) {
4901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_old_generation_size_ = static_cast<intptr_t>(max_old_space_size) * MB;
4902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (max_executable_size > 0) {
4904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_executable_size_ = static_cast<intptr_t>(max_executable_size) * MB;
4905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If max space size flags are specified overwrite the configuration.
4908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_max_semi_space_size > 0) {
4909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    max_semi_space_size_ = FLAG_max_semi_space_size * MB;
4910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_max_old_space_size > 0) {
4912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_old_generation_size_ =
4913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        static_cast<intptr_t>(FLAG_max_old_space_size) * MB;
4914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_max_executable_size > 0) {
4916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_executable_size_ = static_cast<intptr_t>(FLAG_max_executable_size) * MB;
4917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Page::kPageSize > MB) {
4920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_semi_space_size_ = ROUND_UP(max_semi_space_size_, Page::kPageSize);
4921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_old_generation_size_ =
4922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ROUND_UP(max_old_generation_size_, Page::kPageSize);
4923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_executable_size_ = ROUND_UP(max_executable_size_, Page::kPageSize);
4924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_stress_compaction) {
4927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This will cause more frequent GCs when stressing.
4928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    max_semi_space_size_ = Page::kPageSize;
4929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The new space size must be a power of two to support single-bit testing
4932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for containment.
4933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  max_semi_space_size_ =
4934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      base::bits::RoundUpToPowerOfTwo32(max_semi_space_size_);
4935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_min_semi_space_size > 0) {
4937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int initial_semispace_size = FLAG_min_semi_space_size * MB;
4938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (initial_semispace_size > max_semi_space_size_) {
4939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      initial_semispace_size_ = max_semi_space_size_;
4940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_trace_gc) {
4941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrintIsolate(isolate_,
4942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "Min semi-space size cannot be more than the maximum "
4943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     "semi-space size of %d MB\n",
4944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     max_semi_space_size_ / MB);
4945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
4947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      initial_semispace_size_ =
4948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ROUND_UP(initial_semispace_size, Page::kPageSize);
4949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  initial_semispace_size_ = Min(initial_semispace_size_, max_semi_space_size_);
4953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_semi_space_growth_factor < 2) {
4955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    FLAG_semi_space_growth_factor = 2;
4956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
4957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The old generation is paged and needs at least one page for each space.
4959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
4960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  max_old_generation_size_ =
4961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Max(static_cast<intptr_t>(paged_space_count * Page::kPageSize),
4962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          max_old_generation_size_);
4963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The max executable size must be less than or equal to the max old
4965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // generation size.
4966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (max_executable_size_ > max_old_generation_size_) {
4967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    max_executable_size_ = max_old_generation_size_;
4968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_initial_old_space_size > 0) {
4971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    initial_old_generation_size_ = FLAG_initial_old_space_size * MB;
4972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
4973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    initial_old_generation_size_ =
4974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        max_old_generation_size_ / kInitalOldGenerationLimitFactor;
4975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
4976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  old_generation_allocation_limit_ = initial_old_generation_size_;
4977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We rely on being able to allocate new arrays in paged spaces.
4979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(Page::kMaxRegularHeapObjectSize >=
4980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (JSArray::kSize +
4981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          FixedArray::SizeFor(JSArray::kInitialMaxFastElementArray) +
4982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          AllocationMemento::kSize));
4983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  code_range_size_ = code_range_size * MB;
4985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  configured_ = true;
4987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
4988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddToRingBuffer(const char* string) {
4992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t first_part =
4993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Min(strlen(string), kTraceRingBufferSize - ring_buffer_end_);
4994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  memcpy(trace_ring_buffer_ + ring_buffer_end_, string, first_part);
4995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ring_buffer_end_ += first_part;
4996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (first_part < strlen(string)) {
4997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ring_buffer_full_ = true;
4998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t second_part = strlen(string) - first_part;
4999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    memcpy(trace_ring_buffer_, string + first_part, second_part);
5000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ring_buffer_end_ = second_part;
5001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::GetFromRingBuffer(char* buffer) {
5006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t copied = 0;
5007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (ring_buffer_full_) {
5008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    copied = kTraceRingBufferSize - ring_buffer_end_;
5009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    memcpy(buffer, trace_ring_buffer_ + ring_buffer_end_, copied);
5010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  memcpy(buffer + copied, trace_ring_buffer_, ring_buffer_end_);
5012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::ConfigureHeapDefault() { return ConfigureHeap(0, 0, 0, 0); }
5016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
5019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->start_marker = HeapStats::kStartMarker;
5020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->end_marker = HeapStats::kEndMarker;
5021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->new_space_size = new_space_.SizeAsInt();
5022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->new_space_capacity = static_cast<int>(new_space_.Capacity());
5023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *stats->old_space_size = old_space_->SizeOfObjects();
5024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *stats->old_space_capacity = old_space_->Capacity();
5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->code_space_size = code_space_->SizeOfObjects();
5026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->code_space_capacity = code_space_->Capacity();
5027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->map_space_size = map_space_->SizeOfObjects();
5028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->map_space_capacity = map_space_->Capacity();
5029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->lo_space_size = lo_space_->Size();
5030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->global_handles()->RecordStats(stats);
5031bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  *stats->memory_allocator_size = memory_allocator()->Size();
5032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->memory_allocator_capacity =
5033bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      memory_allocator()->Size() + memory_allocator()->Available();
5034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *stats->os_error = base::OS::GetLastError();
5035bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  memory_allocator()->Available();
5036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (take_snapshot) {
5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HeapIterator iterator(this);
5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (HeapObject* obj = iterator.next(); obj != NULL;
5039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         obj = iterator.next()) {
5040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      InstanceType type = obj->map()->instance_type();
5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(0 <= type && type <= LAST_TYPE);
5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stats->objects_per_type[type]++;
5043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stats->size_per_type[type] += obj->Size();
5044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (stats->last_few_messages != NULL)
5047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GetFromRingBuffer(stats->last_few_messages);
5048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (stats->js_stacktrace != NULL) {
5049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FixedStringAllocator fixed(stats->js_stacktrace, kStacktraceBufferSize - 1);
5050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StringStream accumulator(&fixed, StringStream::kPrintObjectConcise);
5051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (gc_state() == Heap::NOT_IN_GC) {
5052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate()->PrintStack(&accumulator, Isolate::kPrintStackVerbose);
5053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
5054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      accumulator.Add("Cannot get stack trace in GC.");
5055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochintptr_t Heap::PromotedSpaceSizeOfObjects() {
5061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return old_space_->SizeOfObjects() + code_space_->SizeOfObjects() +
5062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         map_space_->SizeOfObjects() + lo_space_->SizeOfObjects();
5063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint64_t Heap::PromotedExternalMemorySize() {
5067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (amount_of_external_allocated_memory_ <=
5068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      amount_of_external_allocated_memory_at_last_global_gc_)
5069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
5070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return amount_of_external_allocated_memory_ -
5071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         amount_of_external_allocated_memory_at_last_global_gc_;
5072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kMinHeapGrowingFactor = 1.1;
5076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kMaxHeapGrowingFactor = 4.0;
5077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kMaxHeapGrowingFactorMemoryConstrained = 2.0;
5078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kMaxHeapGrowingFactorIdle = 1.5;
5079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst double Heap::kTargetMutatorUtilization = 0.97;
5080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Given GC speed in bytes per ms, the allocation throughput in bytes per ms
5083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// (mutator speed), this function returns the heap growing factor that will
5084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// achieve the kTargetMutatorUtilisation if the GC speed and the mutator speed
5085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// remain the same until the next GC.
5086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// For a fixed time-frame T = TM + TG, the mutator utilization is the ratio
5088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TM / (TM + TG), where TM is the time spent in the mutator and TG is the
5089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// time spent in the garbage collector.
5090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Let MU be kTargetMutatorUtilisation, the desired mutator utilization for the
5092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// time-frame from the end of the current GC to the end of the next GC. Based
5093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// on the MU we can compute the heap growing factor F as
5094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// F = R * (1 - MU) / (R * (1 - MU) - MU), where R = gc_speed / mutator_speed.
5096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// This formula can be derived as follows.
5098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//
5099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// F = Limit / Live by definition, where the Limit is the allocation limit,
5100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// and the Live is size of live objects.
5101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Let’s assume that we already know the Limit. Then:
5102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TG = Limit / gc_speed
5103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TM = (TM + TG) * MU, by definition of MU.
5104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TM = TG * MU / (1 - MU)
5105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TM = Limit *  MU / (gc_speed * (1 - MU))
5106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// On the other hand, if the allocation throughput remains constant:
5107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   Limit = Live + TM * allocation_throughput = Live + TM * mutator_speed
5108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Solving it for TM, we get
5109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   TM = (Limit - Live) / mutator_speed
5110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Combining the two equation for TM:
5111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   (Limit - Live) / mutator_speed = Limit * MU / (gc_speed * (1 - MU))
5112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   (Limit - Live) = Limit * MU * mutator_speed / (gc_speed * (1 - MU))
5113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// substitute R = gc_speed / mutator_speed
5114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   (Limit - Live) = Limit * MU  / (R * (1 - MU))
5115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// substitute F = Limit / Live
5116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F - 1 = F * MU  / (R * (1 - MU))
5117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F - F * MU / (R * (1 - MU)) = 1
5118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F * (1 - MU / (R * (1 - MU))) = 1
5119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F * (R * (1 - MU) - MU) / (R * (1 - MU)) = 1
5120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   F = R * (1 - MU) / (R * (1 - MU) - MU)
5121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochdouble Heap::HeapGrowingFactor(double gc_speed, double mutator_speed) {
5122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (gc_speed == 0 || mutator_speed == 0) return kMaxHeapGrowingFactor;
5123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double speed_ratio = gc_speed / mutator_speed;
5125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double mu = kTargetMutatorUtilization;
5126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double a = speed_ratio * (1 - mu);
5128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double b = speed_ratio * (1 - mu) - mu;
5129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The factor is a / b, but we need to check for small b first.
5131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double factor =
5132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      (a < b * kMaxHeapGrowingFactor) ? a / b : kMaxHeapGrowingFactor;
5133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  factor = Min(factor, kMaxHeapGrowingFactor);
5134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  factor = Max(factor, kMinHeapGrowingFactor);
5135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return factor;
5136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochintptr_t Heap::CalculateOldGenerationAllocationLimit(double factor,
5140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                     intptr_t old_gen_size) {
5141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(factor > 1.0);
5142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(old_gen_size > 0);
5143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t limit = static_cast<intptr_t>(old_gen_size * factor);
5144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  limit = Max(limit, old_gen_size + kMinimumOldGenerationAllocationLimit);
5145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  limit += new_space_.Capacity();
5146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
5147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Min(limit, halfway_to_the_max);
5148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
5152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           double gc_speed,
5153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           double mutator_speed) {
5154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const double kConservativeHeapGrowingFactor = 1.3;
5155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double factor = HeapGrowingFactor(gc_speed, mutator_speed);
5157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_gc_verbose) {
5159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintIsolate(isolate_,
5160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f "
5161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 "(gc=%.f, mutator=%.f)\n",
5162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 factor, kTargetMutatorUtilization, gc_speed / mutator_speed,
5163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 gc_speed, mutator_speed);
5164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We set the old generation growing factor to 2 to grow the heap slower on
5167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // memory-constrained devices.
5168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice ||
5169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FLAG_optimize_for_size) {
5170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained);
5171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (memory_reducer_->ShouldGrowHeapSlowly() || optimize_for_memory_usage_) {
5174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    factor = Min(factor, kConservativeHeapGrowingFactor);
5175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_stress_compaction || ShouldReduceMemory()) {
5178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    factor = kMinHeapGrowingFactor;
5179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_heap_growing_percent > 0) {
5182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    factor = 1.0 + FLAG_heap_growing_percent / 100.0;
5183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  old_generation_allocation_limit_ =
5186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_trace_gc_verbose) {
5189bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrintIsolate(isolate_, "Grow: old size: %" V8PRIdPTR
5190bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           " KB, new limit: %" V8PRIdPTR " KB (%.1f)\n",
5191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 old_gen_size / KB, old_generation_allocation_limit_ / KB,
5192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 factor);
5193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size,
5198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              double gc_speed,
5199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              double mutator_speed) {
5200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double factor = HeapGrowingFactor(gc_speed, mutator_speed);
5201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  intptr_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (limit < old_generation_allocation_limit_) {
5203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FLAG_trace_gc_verbose) {
5204bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      PrintIsolate(isolate_,
5205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                   "Dampen: old size: %" V8PRIdPTR " KB, old limit: %" V8PRIdPTR
5206bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                   " KB, "
5207bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                   "new limit: %" V8PRIdPTR " KB (%.1f)\n",
5208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   old_gen_size / KB, old_generation_allocation_limit_ / KB,
5209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   limit / KB, factor);
5210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    old_generation_allocation_limit_ = limit;
5212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::EnableInlineAllocation() {
5217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!inline_allocation_disabled_) return;
5218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline_allocation_disabled_ = false;
5219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update inline allocation limit for new space.
5221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space()->UpdateInlineAllocationLimit(0);
5222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::DisableInlineAllocation() {
5226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (inline_allocation_disabled_) return;
5227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline_allocation_disabled_ = true;
5228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update inline allocation limit for new space.
5230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space()->UpdateInlineAllocationLimit(0);
5231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update inline allocation limit for old spaces.
5233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PagedSpaces spaces(this);
5234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (PagedSpace* space = spaces.next(); space != NULL;
5235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       space = spaces.next()) {
5236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    space->EmptyAllocationInfo();
5237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochV8_DECLARE_ONCE(initialize_gc_once);
5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void InitializeGCOnce() {
5244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scavenger::Initialize();
5245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StaticScavengeVisitor::Initialize();
5246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MarkCompactCollector::Initialize();
5247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::SetUp() {
5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
5252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  allocation_timeout_ = FLAG_gc_interval;
5253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
5254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize heap spaces and initial maps and objects. Whenever something
5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // goes wrong, just return false. The caller should check the results and
5257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // call Heap::TearDown() to release allocated memory.
5258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
5259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the heap is not yet configured (e.g. through the API), configure it.
5260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Configuration is based on the flags new-space-size (really the semispace
5261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // size) and old-space-size if set or the initial values of semispace_size_
5262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and old_generation_size_ otherwise.
5263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!configured_) {
5264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!ConfigureHeapDefault()) return false;
5265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::CallOnce(&initialize_gc_once, &InitializeGCOnce);
5268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up memory allocator.
5270bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  memory_allocator_ = new MemoryAllocator(isolate_);
5271bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (!memory_allocator_->SetUp(MaxReserved(), MaxExecutableSize(),
5272bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                code_range_size_))
5273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
5274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Initialize incremental marking.
5276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incremental_marking_ = new IncrementalMarking(this);
5277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up new space.
52793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!new_space_.SetUp(initial_semispace_size_, max_semi_space_size_)) {
5280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
5281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_top_after_last_gc_ = new_space()->top();
5283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Initialize old space.
5285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  old_space_ = new OldSpace(this, OLD_SPACE, NOT_EXECUTABLE);
5286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (old_space_ == NULL) return false;
5287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!old_space_->SetUp()) return false;
5288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize the code space, set its maximum capacity to the old
5290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generation size. It needs executable memory.
5291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  code_space_ = new OldSpace(this, CODE_SPACE, EXECUTABLE);
5292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (code_space_ == NULL) return false;
5293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!code_space_->SetUp()) return false;
5294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize map space.
5296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  map_space_ = new MapSpace(this, MAP_SPACE);
5297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (map_space_ == NULL) return false;
5298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!map_space_->SetUp()) return false;
5299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The large object code space may contain code or data.  We set the memory
5301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to be non-executable here for safety, but this means we need to enable it
5302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // explicitly when allocating large code objects.
5303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  lo_space_ = new LargeObjectSpace(this, LO_SPACE);
5304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lo_space_ == NULL) return false;
5305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!lo_space_->SetUp()) return false;
5306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up the seed that is used to randomize the string hash function.
5308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(hash_seed() == 0);
5309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_randomize_hashes) {
5310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_hash_seed == 0) {
5311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int rnd = isolate()->random_number_generator()->NextInt();
5312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_hash_seed(Smi::FromInt(rnd & Name::kHashBitMask));
5313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
5314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      set_hash_seed(Smi::FromInt(FLAG_hash_seed));
5315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount);
5319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       i++) {
5320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    deferred_counters_[i] = 0;
5321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer_ = new GCTracer(this);
5324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_collector_ = new Scavenger(this);
5326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mark_compact_collector_ = new MarkCompactCollector(this);
5328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  gc_idle_time_handler_ = new GCIdleTimeHandler();
5330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  memory_reducer_ = new MemoryReducer(this);
5332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  object_stats_ = new ObjectStats(this);
5334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  object_stats_->ClearObjectStats(true);
5335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_job_ = new ScavengeJob();
5337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array_buffer_tracker_ = new ArrayBufferTracker(this);
5339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
5341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG(isolate_, IntPtrTEvent("heap-available", Available()));
5342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_buffer()->SetUp();
5344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  mark_compact_collector()->SetUp();
5346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  idle_scavenge_observer_ = new IdleScavengeObserver(
5348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *this, ScavengeJob::kBytesAllocatedBeforeNextIdleTask);
5349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  new_space()->AddAllocationObserver(idle_scavenge_observer_);
5350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
5352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Heap::CreateHeapObjects() {
5356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create initial maps.
5357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!CreateInitialMaps()) return false;
5358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CreateApiObjects();
5359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create initial objects
5361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CreateInitialObjects();
5362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_EQ(0u, gc_count_);
5363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_native_contexts_list(undefined_value());
5365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_allocation_sites_list(undefined_value());
5366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
5368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::SetStackLimits() {
5372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate_ != NULL);
5373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate_ == isolate());
5374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // On 64 bit machines, pointers are generally out of range of Smis.  We write
5375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // something that looks like an out of range Smi to the GC.
5376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up the special root array entries containing the stack limits.
5378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // These are actually addresses, but the tag makes the GC ignore it.
5379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  roots_[kStackLimitRootIndex] = reinterpret_cast<Object*>(
5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag);
5381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  roots_[kRealStackLimitRootIndex] = reinterpret_cast<Object*>(
5382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag);
5383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::ClearStackLimits() {
53863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  roots_[kStackLimitRootIndex] = Smi::FromInt(0);
53873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  roots_[kRealStackLimitRootIndex] = Smi::FromInt(0);
53883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
5389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::PrintAlloctionsHash() {
5391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t hash = StringHasher::GetHashCore(raw_allocations_hash_);
5392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintF("\n### Allocations = %u, hash = 0x%08x\n", allocations_count(), hash);
5393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::NotifyDeserializationComplete() {
5397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  deserialization_complete_ = true;
5398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG
5399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // All pages right after bootstrapping must be marked as never-evacuate.
5400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PagedSpaces spaces(this);
5401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (PagedSpace* s = spaces.next(); s != NULL; s = spaces.next()) {
5402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PageIterator it(s);
5403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (it.has_next()) CHECK(it.next()->NeverEvacuate());
5404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // DEBUG
5406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5408bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
5409bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  mark_compact_collector()->SetEmbedderHeapTracer(tracer);
5410bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
5411bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5412bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool Heap::UsingEmbedderHeapTracer() {
5413bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return mark_compact_collector()->UsingEmbedderHeapTracer();
5414bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
5415bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5416bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid Heap::TracePossibleWrapper(JSObject* js_object) {
5417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  mark_compact_collector()->TracePossibleWrapper(js_object);
5418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
5419bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
54203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::RegisterExternallyReferencedObject(Object** object) {
5421bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  mark_compact_collector()->RegisterExternallyReferencedObject(object);
54223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
5423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TearDown() {
5425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
5426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
5427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Verify();
5428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
5430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateMaximumCommitted();
5432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_print_cumulative_gc_stat) {
5434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("\n");
5435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("gc_count=%d ", gc_count_);
5436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("mark_sweep_count=%d ", ms_count_);
5437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("max_gc_pause=%.1f ", get_max_gc_pause());
5438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("total_gc_time=%.1f ", total_gc_time_ms_);
5439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("min_in_mutator=%.1f ", get_min_in_mutator());
5440bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrintF("max_alive_after_gc=%" V8PRIdPTR " ", get_max_alive_after_gc());
5441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("total_marking_time=%.1f ", tracer()->cumulative_marking_duration());
5442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("total_sweeping_time=%.1f ",
5443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           tracer()->cumulative_sweeping_duration());
5444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("\n\n");
5445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_print_max_heap_committed) {
5448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("\n");
5449bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrintF("maximum_committed_by_heap=%" V8PRIdPTR " ",
5450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           MaximumCommittedMemory());
5451bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrintF("maximum_committed_by_new_space=%" V8PRIdPTR " ",
5452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           new_space_.MaximumCommittedMemory());
5453bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrintF("maximum_committed_by_old_space=%" V8PRIdPTR " ",
5454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           old_space_->MaximumCommittedMemory());
5455bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrintF("maximum_committed_by_code_space=%" V8PRIdPTR " ",
5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           code_space_->MaximumCommittedMemory());
5457bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrintF("maximum_committed_by_map_space=%" V8PRIdPTR " ",
5458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           map_space_->MaximumCommittedMemory());
5459bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrintF("maximum_committed_by_lo_space=%" V8PRIdPTR " ",
5460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           lo_space_->MaximumCommittedMemory());
5461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("\n\n");
5462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_predictable) {
5465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintAlloctionsHash();
5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5468109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  new_space()->RemoveAllocationObserver(idle_scavenge_observer_);
5469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete idle_scavenge_observer_;
5470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  idle_scavenge_observer_ = nullptr;
5471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete scavenge_collector_;
5473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_collector_ = nullptr;
5474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mark_compact_collector_ != nullptr) {
5476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    mark_compact_collector_->TearDown();
5477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete mark_compact_collector_;
5478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    mark_compact_collector_ = nullptr;
5479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete incremental_marking_;
5482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incremental_marking_ = nullptr;
5483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete gc_idle_time_handler_;
5485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  gc_idle_time_handler_ = nullptr;
5486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (memory_reducer_ != nullptr) {
5488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    memory_reducer_->TearDown();
5489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete memory_reducer_;
5490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    memory_reducer_ = nullptr;
5491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete object_stats_;
5494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  object_stats_ = nullptr;
5495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete scavenge_job_;
5497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  scavenge_job_ = nullptr;
5498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete array_buffer_tracker_;
5500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array_buffer_tracker_ = nullptr;
5501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->global_handles()->TearDown();
5503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  external_string_table_.TearDown();
5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete tracer_;
5507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  tracer_ = nullptr;
5508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_.TearDown();
5510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (old_space_ != NULL) {
5512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete old_space_;
5513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    old_space_ = NULL;
5514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (code_space_ != NULL) {
5517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete code_space_;
5518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code_space_ = NULL;
5519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (map_space_ != NULL) {
5522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete map_space_;
5523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    map_space_ = NULL;
5524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lo_space_ != NULL) {
5527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    lo_space_->TearDown();
5528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete lo_space_;
5529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    lo_space_ = NULL;
5530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  store_buffer()->TearDown();
5533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5534bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  memory_allocator()->TearDown();
5535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* next = NULL;
5537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (StrongRootsList* list = strong_roots_list_; list; list = next) {
5538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next = list->next;
5539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delete list;
5540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  strong_roots_list_ = NULL;
5542bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5543bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  delete memory_allocator_;
5544bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  memory_allocator_ = nullptr;
5545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddGCPrologueCallback(v8::Isolate::GCCallback callback,
5549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 GCType gc_type, bool pass_isolate) {
5550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callback != NULL);
5551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCCallbackPair pair(callback, gc_type, pass_isolate);
5552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!gc_prologue_callbacks_.Contains(pair));
5553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return gc_prologue_callbacks_.Add(pair);
5554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RemoveGCPrologueCallback(v8::Isolate::GCCallback callback) {
5558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callback != NULL);
5559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
5560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (gc_prologue_callbacks_[i].callback == callback) {
5561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_prologue_callbacks_.Remove(i);
5562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
5563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
5566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddGCEpilogueCallback(v8::Isolate::GCCallback callback,
5570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 GCType gc_type, bool pass_isolate) {
5571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callback != NULL);
5572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCCallbackPair pair(callback, gc_type, pass_isolate);
5573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!gc_epilogue_callbacks_.Contains(pair));
5574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return gc_epilogue_callbacks_.Add(pair);
5575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RemoveGCEpilogueCallback(v8::Isolate::GCCallback callback) {
5579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callback != NULL);
5580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
5581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (gc_epilogue_callbacks_[i].callback == callback) {
5582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_epilogue_callbacks_.Remove(i);
5583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
5584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
5587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(ishell): Find a better place for this.
5590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj,
5591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Handle<DependentCode> dep) {
5592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(*obj));
5593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!InNewSpace(*dep));
5594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<WeakHashTable> table(weak_object_to_code_table(), isolate());
5595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  table = WeakHashTable::Put(table, obj, dep);
5596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (*table != weak_object_to_code_table())
5597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_weak_object_to_code_table(*table);
5598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj));
5599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDependentCode* Heap::LookupWeakObjectToCodeDependency(Handle<HeapObject> obj) {
5603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* dep = weak_object_to_code_table()->Lookup(obj);
5604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dep->IsDependentCode()) return DependentCode::cast(dep);
5605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DependentCode::cast(empty_fixed_array());
5606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::AddRetainedMap(Handle<Map> map) {
5610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<WeakCell> cell = Map::WeakCellForMap(map);
5611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<ArrayList> array(retained_maps(), isolate());
5612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (array->IsFull()) {
5613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CompactRetainedMaps(*array);
5614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  array = ArrayList::Add(
5616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array, cell, handle(Smi::FromInt(FLAG_retain_maps_for_n_gc), isolate()),
5617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ArrayList::kReloadLengthAfterAllocation);
5618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (*array != retained_maps()) {
5619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_retained_maps(*array);
5620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::CompactRetainedMaps(ArrayList* retained_maps) {
5625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(retained_maps, this->retained_maps());
5626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length = retained_maps->Length();
5627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_length = 0;
5628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_number_of_disposed_maps = 0;
5629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This loop compacts the array by removing cleared weak cells.
5630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < length; i += 2) {
5631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(retained_maps->Get(i)->IsWeakCell());
5632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    WeakCell* cell = WeakCell::cast(retained_maps->Get(i));
5633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object* age = retained_maps->Get(i + 1);
5634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (cell->cleared()) continue;
5635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i != new_length) {
5636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      retained_maps->Set(new_length, cell);
5637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      retained_maps->Set(new_length + 1, age);
5638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i < number_of_disposed_maps_) {
5640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new_number_of_disposed_maps += 2;
5641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    new_length += 2;
5643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  number_of_disposed_maps_ = new_number_of_disposed_maps;
5645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* undefined = undefined_value();
5646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = new_length; i < length; i++) {
5647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    retained_maps->Clear(i, undefined);
5648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_length != length) retained_maps->SetLength(new_length);
5650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5652bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid Heap::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) {
5653bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  v8::internal::V8::FatalProcessOutOfMemory(location, is_heap_oom);
5654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
5657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PrintHandleVisitor : public ObjectVisitor {
5659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
5660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
5661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Object** p = start; p < end; p++)
5662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF("  handle %p to %p\n", reinterpret_cast<void*>(p),
5663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             reinterpret_cast<void*>(*p));
5664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::PrintHandles() {
5669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintF("Handles:\n");
5670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintHandleVisitor v;
5671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->handle_scope_implementer()->Iterate(&v);
5672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
5675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CheckHandleCountVisitor : public ObjectVisitor {
5677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
5678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckHandleCountVisitor() : handle_count_(0) {}
5679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ~CheckHandleCountVisitor() override {
5680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(handle_count_ < HandleScope::kCheckHandleThreshold);
5681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
5683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    handle_count_ += end - start;
5684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
5685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
5687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ptrdiff_t handle_count_;
5688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
5689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::CheckHandleCount() {
5692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckHandleCountVisitor v;
5693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate_->handle_scope_implementer()->Iterate(&v);
5694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5696109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid Heap::ClearRecordedSlot(HeapObject* object, Object** slot) {
5697109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!InNewSpace(object)) {
5698109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    store_buffer()->MoveEntriesToRememberedSet();
5699109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Address slot_addr = reinterpret_cast<Address>(slot);
5700109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Page* page = Page::FromAddress(slot_addr);
5701109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
5702109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    RememberedSet<OLD_TO_NEW>::Remove(page, slot_addr);
57033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    RememberedSet<OLD_TO_OLD>::Remove(page, slot_addr);
5704109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
5705109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
5706109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
57073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Heap::ClearRecordedSlotRange(Address start, Address end) {
57083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Page* page = Page::FromAddress(start);
57093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!page->InNewSpace()) {
5710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    store_buffer()->MoveEntriesToRememberedSet();
5711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK_EQ(page->owner()->identity(), OLD_SPACE);
57123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end);
57133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    RememberedSet<OLD_TO_OLD>::RemoveRange(page, start, end);
5714109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
5715109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpace* AllSpaces::next() {
5718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (counter_++) {
5719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NEW_SPACE:
5720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->new_space();
5721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
5722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return heap_->old_space();
5723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_SPACE:
5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->code_space();
5725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case MAP_SPACE:
5726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->map_space();
5727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LO_SPACE:
5728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->lo_space();
5729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
5730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
5731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPagedSpace* PagedSpaces::next() {
5736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (counter_++) {
5737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
5738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return heap_->old_space();
5739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_SPACE:
5740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->code_space();
5741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case MAP_SPACE:
5742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->map_space();
5743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
5744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
5745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOldSpace* OldSpaces::next() {
5750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (counter_++) {
5751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
5752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return heap_->old_space();
5753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_SPACE:
5754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return heap_->code_space();
5755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
5756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
5757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpaceIterator::SpaceIterator(Heap* heap)
5762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : heap_(heap), current_space_(FIRST_SPACE), iterator_(NULL) {}
5763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSpaceIterator::~SpaceIterator() {
5766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Delete active iterator if any.
5767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete iterator_;
5768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool SpaceIterator::has_next() {
5772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate until no more spaces.
5773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return current_space_ != LAST_SPACE;
5774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObjectIterator* SpaceIterator::next() {
5778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (iterator_ != NULL) {
5779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete iterator_;
5780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    iterator_ = NULL;
5781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Move to the next space
5782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current_space_++;
5783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current_space_ > LAST_SPACE) {
5784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
5785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return iterator for the new current space.
5789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return CreateIterator();
5790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Create an iterator for the space to iterate.
5794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObjectIterator* SpaceIterator::CreateIterator() {
5795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(iterator_ == NULL);
5796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (current_space_) {
5798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NEW_SPACE:
5799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      iterator_ = new SemiSpaceIterator(heap_->new_space());
5800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OLD_SPACE:
5802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      iterator_ = new HeapObjectIterator(heap_->old_space());
5803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_SPACE:
5805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      iterator_ = new HeapObjectIterator(heap_->code_space());
5806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case MAP_SPACE:
5808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      iterator_ = new HeapObjectIterator(heap_->map_space());
5809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case LO_SPACE:
5811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      iterator_ = new LargeObjectIterator(heap_->lo_space());
5812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return the newly allocated iterator;
5816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(iterator_ != NULL);
5817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return iterator_;
5818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HeapObjectsFilter {
5822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
5823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~HeapObjectsFilter() {}
5824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool SkipObject(HeapObject* object) = 0;
5825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass UnreachableObjectsFilter : public HeapObjectsFilter {
5829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
5830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit UnreachableObjectsFilter(Heap* heap) : heap_(heap) {
5831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkReachableObjects();
5832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~UnreachableObjectsFilter() {
5835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_->mark_compact_collector()->ClearMarkbits();
5836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool SkipObject(HeapObject* object) {
5839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (object->IsFiller()) return true;
5840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkBit mark_bit = Marking::MarkBitFrom(object);
5841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Marking::IsWhite(mark_bit);
5842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
5845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class MarkingVisitor : public ObjectVisitor {
5846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
5847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkingVisitor() : marking_stack_(10) {}
5848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void VisitPointers(Object** start, Object** end) override {
5850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (Object** p = start; p < end; p++) {
5851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!(*p)->IsHeapObject()) continue;
5852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HeapObject* obj = HeapObject::cast(*p);
5853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        MarkBit mark_bit = Marking::MarkBitFrom(obj);
5854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (Marking::IsWhite(mark_bit)) {
5855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Marking::WhiteToBlack(mark_bit);
5856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          marking_stack_.Add(obj);
5857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
5858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
5859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void TransitiveClosure() {
5862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      while (!marking_stack_.is_empty()) {
5863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HeapObject* obj = marking_stack_.RemoveLast();
5864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        obj->Iterate(this);
5865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
5866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
5869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    List<HeapObject*> marking_stack_;
5870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
5871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkReachableObjects() {
5873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MarkingVisitor visitor;
5874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_->IterateRoots(&visitor, VISIT_ALL);
5875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor.TransitiveClosure();
5876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap* heap_;
5879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation_;
5880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapIterator::HeapIterator(Heap* heap,
5884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           HeapIterator::HeapObjectsFiltering filtering)
5885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : make_heap_iterable_helper_(heap),
5886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      no_heap_allocation_(),
5887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      heap_(heap),
5888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      filtering_(filtering),
5889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      filter_(nullptr),
5890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      space_iterator_(nullptr),
5891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      object_iterator_(nullptr) {
5892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  heap_->heap_iterator_start();
5893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Start the iteration.
5894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  space_iterator_ = new SpaceIterator(heap_);
5895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (filtering_) {
5896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kFilterUnreachable:
5897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      filter_ = new UnreachableObjectsFilter(heap_);
5898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
5900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
5901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object_iterator_ = space_iterator_->next();
5903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHeapIterator::~HeapIterator() {
5907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  heap_->heap_iterator_end();
5908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
5909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assert that in filtering mode we have iterated through all
5910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects. Otherwise, heap will be left in an inconsistent state.
5911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (filtering_ != kNoFiltering) {
5912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(object_iterator_ == nullptr);
5913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
5915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Make sure the last iterator is deallocated.
5916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  delete object_iterator_;
5917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete space_iterator_;
5918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete filter_;
5919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapObject* HeapIterator::next() {
5923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (filter_ == nullptr) return NextObject();
5924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject* obj = NextObject();
5926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while ((obj != nullptr) && (filter_->SkipObject(obj))) obj = NextObject();
5927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj;
5928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapObject* HeapIterator::NextObject() {
5932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No iterator means we are done.
5933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (object_iterator_ == nullptr) return nullptr;
5934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HeapObject* obj = object_iterator_->next_object()) {
5936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the current iterator has more objects we are fine.
5937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return obj;
5938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
5939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Go though the spaces looking for one that has objects.
5940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (space_iterator_->has_next()) {
5941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object_iterator_ = space_iterator_->next();
5942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (HeapObject* obj = object_iterator_->next_object()) {
5943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return obj;
5944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
5945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Done with the last space.
5948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  object_iterator_ = nullptr;
5949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
5950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
5954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject* const PathTracer::kAnyGlobalObject = NULL;
5956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PathTracer::MarkVisitor : public ObjectVisitor {
5958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
5959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit MarkVisitor(PathTracer* tracer) : tracer_(tracer) {}
5960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
5962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Scan all HeapObject pointers in [start, end)
5963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Object** p = start; !tracer_->found() && (p < end); p++) {
5964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if ((*p)->IsHeapObject()) tracer_->MarkRecursively(p, this);
5965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
5969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PathTracer* tracer_;
5970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PathTracer::UnmarkVisitor : public ObjectVisitor {
5974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
5975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit UnmarkVisitor(PathTracer* tracer) : tracer_(tracer) {}
5976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitPointers(Object** start, Object** end) override {
5978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Scan all HeapObject pointers in [start, end)
5979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (Object** p = start; p < end; p++) {
5980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if ((*p)->IsHeapObject()) tracer_->UnmarkRecursively(p, this);
5981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
5985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PathTracer* tracer_;
5986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::VisitPointers(Object** start, Object** end) {
5990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool done = ((what_to_find_ == FIND_FIRST) && found_target_);
5991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit all HeapObject pointers in [start, end)
5992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (Object** p = start; !done && (p < end); p++) {
5993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((*p)->IsHeapObject()) {
5994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TracePathFrom(p);
5995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      done = ((what_to_find_ == FIND_FIRST) && found_target_);
5996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::Reset() {
6002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  found_target_ = false;
6003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object_stack_.Clear();
6004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::TracePathFrom(Object** root) {
6008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((search_target_ == kAnyGlobalObject) ||
6009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         search_target_->IsHeapObject());
6010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  found_target_in_trace_ = false;
6011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reset();
6012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MarkVisitor mark_visitor(this);
6014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MarkRecursively(root, &mark_visitor);
6015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UnmarkVisitor unmark_visitor(this);
6017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UnmarkRecursively(root, &unmark_visitor);
6018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ProcessResults();
6020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool SafeIsNativeContext(HeapObject* obj) {
6024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return obj->map() == obj->GetHeap()->root(Heap::kNativeContextMapRootIndex);
6025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) {
6029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!(*p)->IsHeapObject()) return;
6030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject* obj = HeapObject::cast(*p);
6032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapWord map_word = obj->map_word();
6034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!map_word.ToMap()->IsHeapObject()) return;  // visited before
6035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (found_target_in_trace_) return;  // stop if target found
6037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  object_stack_.Add(obj);
6038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (((search_target_ == kAnyGlobalObject) && obj->IsJSGlobalObject()) ||
6039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (obj == search_target_)) {
6040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    found_target_in_trace_ = true;
6041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    found_target_ = true;
6042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
6043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_native_context = SafeIsNativeContext(obj);
6046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // not visited yet
6048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = Map::cast(map_word.ToMap());
6049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapWord marked_map_word =
6051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MapWord::FromRawValue(obj->map_word().ToRawValue() + kMarkTag);
6052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_map_word(marked_map_word);
6053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Scan the object body.
6055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_native_context && (visit_mode_ == VISIT_ONLY_STRONG)) {
6056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is specialized to scan Context's properly.
6057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** start =
6058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<Object**>(obj->address() + Context::kHeaderSize);
6059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** end =
6060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<Object**>(obj->address() + Context::kHeaderSize +
6061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   Context::FIRST_WEAK_SLOT * kPointerSize);
6062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    mark_visitor->VisitPointers(start, end);
6063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
6064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    obj->IterateBody(map->instance_type(), obj->SizeFromMap(map), mark_visitor);
6065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Scan the map after the body because the body is a lot more interesting
6068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // when doing leak detection.
6069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MarkRecursively(reinterpret_cast<Object**>(&map), mark_visitor);
6070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!found_target_in_trace_) {  // don't pop if found the target
6072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object_stack_.RemoveLast();
6073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::UnmarkRecursively(Object** p, UnmarkVisitor* unmark_visitor) {
6078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!(*p)->IsHeapObject()) return;
6079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject* obj = HeapObject::cast(*p);
6081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapWord map_word = obj->map_word();
6083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (map_word.ToMap()->IsHeapObject()) return;  // unmarked already
6084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapWord unmarked_map_word =
6086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MapWord::FromRawValue(map_word.ToRawValue() - kMarkTag);
6087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_map_word(unmarked_map_word);
6088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* map = Map::cast(unmarked_map_word.ToMap());
6090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UnmarkRecursively(reinterpret_cast<Object**>(&map), unmark_visitor);
6092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->IterateBody(map->instance_type(), obj->SizeFromMap(map), unmark_visitor);
6094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PathTracer::ProcessResults() {
6098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (found_target_) {
6099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    OFStream os(stdout);
6100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os << "=====================================\n"
6101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       << "====        Path to object       ====\n"
6102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       << "=====================================\n\n";
6103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!object_stack_.is_empty());
6105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < object_stack_.length(); i++) {
6106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (i > 0) os << "\n     |\n     |\n     V\n\n";
6107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object_stack_[i]->Print(os);
6108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os << "=====================================\n";
6110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Triggers a depth-first traversal of reachable objects from one
6115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// given root object and finds a path to a specific heap object and
6116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// prints it.
6117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TracePathToObjectFrom(Object* target, Object* root) {
6118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL);
6119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  tracer.VisitPointer(&root);
6120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Triggers a depth-first traversal of reachable objects from roots
6124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and finds a path to a specific heap object and prints it.
6125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TracePathToObject(Object* target) {
6126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL);
6127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateRoots(&tracer, VISIT_ONLY_STRONG);
6128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Triggers a depth-first traversal of reachable objects from roots
6132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and finds a path to any global object and prints it. Useful for
6133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// determining the source for leaks of global objects.
6134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::TracePathToGlobal() {
6135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PathTracer tracer(PathTracer::kAnyGlobalObject, PathTracer::FIND_ALL,
6136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    VISIT_ALL);
6137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IterateRoots(&tracer, VISIT_ONLY_STRONG);
6138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
6140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::UpdateCumulativeGCStatistics(double duration,
6143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        double spent_in_mutator,
6144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        double marking_time) {
6145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_print_cumulative_gc_stat) {
6146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    total_gc_time_ms_ += duration;
6147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    max_gc_pause_ = Max(max_gc_pause_, duration);
6148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    max_alive_after_gc_ = Max(max_alive_after_gc_, SizeOfObjects());
6149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    min_in_mutator_ = Min(min_in_mutator_, spent_in_mutator);
6150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (FLAG_trace_gc_verbose) {
6151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    total_gc_time_ms_ += duration;
6152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  marking_time_ += marking_time;
6155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint KeyedLookupCache::Hash(Handle<Map> map, Handle<Name> name) {
6159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_gc;
6160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Uses only lower 32 bits if pointers are larger.
6161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uintptr_t addr_hash =
6162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<uint32_t>(reinterpret_cast<uintptr_t>(*map)) >> kMapHashShift;
6163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask);
6164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint KeyedLookupCache::Lookup(Handle<Map> map, Handle<Name> name) {
6168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_gc;
6169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index = (Hash(map, name) & kHashMask);
6170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < kEntriesPerBucket; i++) {
6171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Key& key = keys_[index + i];
6172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((key.map == *map) && key.name->Equals(*name)) {
6173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return field_offsets_[index + i];
6174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kNotFound;
6177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid KeyedLookupCache::Update(Handle<Map> map, Handle<Name> name,
6181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              int field_offset) {
6182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_gc;
6183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!name->IsUniqueName()) {
6184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!StringTable::InternalizeStringIfExists(
6185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             name->GetIsolate(), Handle<String>::cast(name)).ToHandle(&name)) {
6186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
6187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This cache is cleared only between mark compact passes, so we expect the
6190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // cache to only contain old space names.
6191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!map->GetIsolate()->heap()->InNewSpace(*name));
6192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index = (Hash(map, name) & kHashMask);
6194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // After a GC there will be free slots, so we use them in order (this may
6195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // help to get the most frequently used one in position 0).
6196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < kEntriesPerBucket; i++) {
6197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Key& key = keys_[index];
6198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* free_entry_indicator = NULL;
6199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (key.map == free_entry_indicator) {
6200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      key.map = *map;
6201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      key.name = *name;
6202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      field_offsets_[index + i] = field_offset;
6203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
6204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No free entry found in this bucket, so we move them all down one and
6207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // put the new entry at position zero.
6208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = kEntriesPerBucket - 1; i > 0; i--) {
6209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Key& key = keys_[index + i];
6210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Key& key2 = keys_[index + i - 1];
6211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    key = key2;
6212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    field_offsets_[index + i] = field_offsets_[index + i - 1];
6213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Write the new first entry.
6216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Key& key = keys_[index];
6217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  key.map = *map;
6218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  key.name = *name;
6219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  field_offsets_[index] = field_offset;
6220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid KeyedLookupCache::Clear() {
6224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int index = 0; index < kLength; index++) keys_[index].map = NULL;
6225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DescriptorLookupCache::Clear() {
6229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int index = 0; index < kLength; index++) keys_[index].source = NULL;
6230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ExternalStringTable::CleanUp() {
6233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int last = 0;
6234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < new_space_strings_.length(); ++i) {
6235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (new_space_strings_[i] == heap_->the_hole_value()) {
6236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continue;
6237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(new_space_strings_[i]->IsExternalString());
6239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (heap_->InNewSpace(new_space_strings_[i])) {
6240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new_space_strings_[last++] = new_space_strings_[i];
6241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
6242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      old_space_strings_.Add(new_space_strings_[i]);
6243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_strings_.Rewind(last);
6246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_strings_.Trim();
6247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last = 0;
6249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < old_space_strings_.length(); ++i) {
6250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (old_space_strings_[i] == heap_->the_hole_value()) {
6251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continue;
6252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(old_space_strings_[i]->IsExternalString());
6254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!heap_->InNewSpace(old_space_strings_[i]));
6255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    old_space_strings_[last++] = old_space_strings_[i];
6256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  old_space_strings_.Rewind(last);
6258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  old_space_strings_.Trim();
6259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP
6260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_verify_heap) {
6261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Verify();
6262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
6264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::ExternalStringTable::TearDown() {
6267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < new_space_strings_.length(); ++i) {
6268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i]));
6269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_space_strings_.Free();
6271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < old_space_strings_.length(); ++i) {
6272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i]));
6273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  old_space_strings_.Free();
6275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Heap::RememberUnmappedPage(Address page, bool compacted) {
6279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uintptr_t p = reinterpret_cast<uintptr_t>(page);
6280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Tag the page pointer to make it findable in the dump file.
6281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (compacted) {
6282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    p ^= 0xc1ead & (Page::kPageSize - 1);  // Cleared.
6283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
6284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    p ^= 0x1d1ed & (Page::kPageSize - 1);  // I died.
6285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  remembered_unmapped_pages_[remembered_unmapped_pages_index_] =
6287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<Address>(p);
6288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  remembered_unmapped_pages_index_++;
6289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  remembered_unmapped_pages_index_ %= kRememberedUnmappedPages;
6290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::RegisterStrongRoots(Object** start, Object** end) {
6294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* list = new StrongRootsList();
6295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  list->next = strong_roots_list_;
6296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  list->start = start;
6297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  list->end = end;
6298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  strong_roots_list_ = list;
6299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Heap::UnregisterStrongRoots(Object** start) {
6303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* prev = NULL;
6304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StrongRootsList* list = strong_roots_list_;
6305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (list != nullptr) {
6306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StrongRootsList* next = list->next;
6307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (list->start == start) {
6308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (prev) {
6309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        prev->next = next;
6310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
6311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        strong_roots_list_ = next;
6312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
6313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      delete list;
6314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
6315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      prev = list;
6316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
6317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    list = next;
6318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
6319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochsize_t Heap::NumberOfTrackedHeapObjectTypes() {
6323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ObjectStats::OBJECT_STATS_COUNT;
6324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochsize_t Heap::ObjectCountAtLastGC(size_t index) {
6328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index >= ObjectStats::OBJECT_STATS_COUNT) return 0;
6329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return object_stats_->object_count_last_gc(index);
6330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochsize_t Heap::ObjectSizeAtLastGC(size_t index) {
6334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index >= ObjectStats::OBJECT_STATS_COUNT) return 0;
6335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return object_stats_->object_size_last_gc(index);
6336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Heap::GetObjectTypeName(size_t index, const char** object_type,
6340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             const char** object_sub_type) {
6341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index >= ObjectStats::OBJECT_STATS_COUNT) return false;
6342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (static_cast<int>(index)) {
6344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define COMPARE_AND_RETURN_NAME(name) \
6345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case name:                          \
6346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_type = #name;             \
6347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_sub_type = "";            \
6348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
6349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    INSTANCE_TYPE_LIST(COMPARE_AND_RETURN_NAME)
6350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef COMPARE_AND_RETURN_NAME
6351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define COMPARE_AND_RETURN_NAME(name)                      \
6352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case ObjectStats::FIRST_CODE_KIND_SUB_TYPE + Code::name: \
6353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_type = "CODE_TYPE";                            \
6354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_sub_type = "CODE_KIND/" #name;                 \
6355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
6356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CODE_KIND_LIST(COMPARE_AND_RETURN_NAME)
6357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef COMPARE_AND_RETURN_NAME
6358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define COMPARE_AND_RETURN_NAME(name)                  \
6359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case ObjectStats::FIRST_FIXED_ARRAY_SUB_TYPE + name: \
6360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_type = "FIXED_ARRAY_TYPE";                 \
6361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_sub_type = #name;                          \
6362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
6363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COMPARE_AND_RETURN_NAME)
6364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef COMPARE_AND_RETURN_NAME
6365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define COMPARE_AND_RETURN_NAME(name)                                  \
6366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case ObjectStats::FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - \
6367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Code::kFirstCodeAge:                                             \
6368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_type = "CODE_TYPE";                                        \
6369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *object_sub_type = "CODE_AGE/" #name;                              \
6370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
6371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME)
6372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef COMPARE_AND_RETURN_NAME
6373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
6374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
6375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
6379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Heap::GetStaticVisitorIdForMap(Map* map) {
6380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return StaticVisitorBase::GetVisitorId(map);
6381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
6382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
6383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
6384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
6385